फील्डफिनिट झंडा पहले क्या करता है?


82

फील्डफिनिट झंडा पहले क्या करता है? जब मैं अपनी कक्षा के आईएल में देखता हूं तो मुझे यह ध्वज दिखाई देता है लेकिन मुझे नहीं पता कि यह ध्वज वास्तव में क्या कर रहा है?

जवाबों:


132

मेरा लेख देखेंइस मुद्दे पर ।

मूल रूप से, beforefieldinitइसका अर्थ है "किसी भी स्थिर फ़ील्ड को संदर्भित करने से पहले किसी भी बिंदु पर प्रकार को आरंभ किया जा सकता है।" सिद्धांत रूप में इसका मतलब है कि यह बहुत आलस्यपूर्ण हो सकता है - यदि आप एक स्थैतिक विधि को कहते हैं जो किसी भी क्षेत्र को नहीं छूती है, तो JIT को इस प्रकार को प्रारंभ करने की आवश्यकता नहीं है।

व्यवहार में इसका मतलब यह है कि वर्ग को पहले की तुलना में प्रारंभिक किया गया है अन्यथा यह होगा - यह ठीक है कि इसे पहली विधि के प्रारंभ में आरंभ किया जाए जो इसका उपयोग कर सकती है। इसकी तुलना उन प्रकारों से करें, जो उन पर लागू नहीं होती beforefieldinitहैं, जहां पहले वास्तविक उपयोग से ठीक पहले टाइप आरंभीकरण होता है ।

तो, मान लीजिए कि हमारे पास है:

public static void DoSomething(bool which)
{
    if (which)
    {
        FirstType.Foo();
    }
    else
    {
        SecondType.Bar();
    }
}

यदि दोनों प्रकारों ने beforefieldinitउन पर लागू किया है (जो कि सी # में वे डिफ़ॉल्ट रूप से करते हैं जब तक कि प्रकार में एक स्थिर निर्माता नहीं है), तो वे दोनोंDoSomething विधि के प्रारंभ में प्रारंभ हो जाएंगे (आमतौर पर - यह गारंटी नहीं है)। यदि उनके पास नहीं है, beforefieldinitतो उनमें से केवल एक को ध्वज के आधार पर आरंभ किया जाएगा।

यही कारण है कि सिंगलटन पैटर्न को लागू करते समय एक स्थिर कंस्ट्रक्टर (यहां तक ​​कि एक खाली!) का उपयोग करना आम है ।


"किसी भी क्षेत्र के संदर्भित होने से पहले किसी भी बिंदु पर प्रकार को आरंभ किया जा सकता है।" क्या यह स्थैतिक विधियों को चलाने के लिए भी सही है?
रॉय नमिर

@RoyiNamir, CLI कल्पना कहती है कि यदि पहलेFFieldInit लागू किया गया है, तो "इस प्रकार के आरंभीकरण विधि को निष्पादित किया जाता है, या कुछ समय पहले, उस प्रकार के लिए परिभाषित किसी भी स्थैतिक क्षेत्र में पहले पहुंच"। यदि वह विशेषता छूट गई है (स्थैतिक। ट्रैक्टर) तो "उस प्रकार के किसी भी स्थिर या आवृत्ति क्षेत्र में पहली पहुँच, या उस प्रकार के किसी भी स्थैतिक, उदाहरण या आभासी पद्धति का पहला आह्वान"। जब तक कि स्थिर विधि किसी अन्य स्थिर फ़ील्ड का संदर्भ नहीं देती है, तब तक यहFFieldInit के लिए लागू नहीं होता है।
अरमान

3
मुझे पता चला कि स्थिर कंस्ट्रक्टर (यानी ऐसी क्लासेस जिनके पास पहले वाला फ्लैगशिप फ्लैग नहीं है) का उपयोग करने के लिए एक प्रदर्शन जुर्माना है। यदि आप किसी निश्चित वर्ग के स्थिर सदस्यों को अक्सर कॉल करते हैं, तो ऐसा लगता है कि रनटाइम को प्रत्येक कॉल से पहले एक अतिरिक्त जांच करनी है, यह जांचने के लिए कि क्या अभी तक टाइप किया गया है; इससे पहले कि इन चेक से बचें। बेंचमार्क के कुछ जोड़े पहले के क्षेत्र के साथ लगभग 50% तेज थे: codeproject.com/Articles/87991/…
Qwertie

6

ऐसा लगता है कि यह 4.6 में बदलने जा रहा है

https://github.com/dotnet/coreclr/issues/1193


बहुत बढ़िया, तो इसका मतलब यह है कि यह क्षेत्र को आरंभ करने के लिए अंतिम क्षण तक इंतजार करेगा (भले ही उसके पास है beforefieldinitया नहीं)?
जेम्स को

1
पहले उपयोग से पहले सभी एक्सेस को इनिशियलाइज़ेशन चेक के साथ प्रीफ़िक्स किया जाएगा। उसके बाद, जब अन्य विधियाँ छोड़ी जाती हैं, तो उत्पन्न कोड सीधे क्षेत्र तक पहुँच जाएगा। यदि यह एक आदिम प्रकार का है तो इसे JIT समय स्थिर के रूप में भी उपयोग किया जा सकता है।
ओमारीओ

2
जॉन की परिवर्तन पर विस्तृत विश्लेषण नेट 4.0 शुरू करने आरंभीकरण टाइप करने के लिए यहां
RBT
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.