नामॉफ () का संकलन-समय पर मूल्यांकन किया जाता है?


114

C # 6 में, आप nameof()एक चर या एक प्रकार के नाम से युक्त स्ट्रिंग प्राप्त करने के लिए ऑपरेटर का उपयोग कर सकते हैं ।

यह संकलन-समय पर मूल्यांकन किया जाता है, या कुछ रोसलिन एपीआई के माध्यम से रनटाइम पर?


रोसलिन नया संकलक मंच है। यह केवल संकलन-समय पर उपयोग किया जाता है।
पाउलो मोर्गादो

2
@PaooMorgado जो सच नहीं है, आप चीजों को करने के लिए रन टाइम पर रोसिलिन का उपयोग कर सकते हैं। जैसे कि एक जीवित कोड संपादक का निर्माण करना या रोज़ाइलन के पार्सिंग सामान का उपयोग पेड़ों या भावों या किसी चीज़ के साथ करने के लिए
क्रिस मैरिसिक

@ChrisMarisic मेरी धारणा है, लेकिन मैंने इस विषय पर मेरे ज्ञान के बाद से कोई प्रतिक्रिया नहीं दी है (इसलिए मेरा प्रश्न)। मुझे यह पता नहीं चला: scriptcs.net जो कि रोसलिन की शक्ति का एक बहुत अच्छा उदाहरण है, और मेरा मानना ​​है कि रनटाइम सामान है, लेकिन मैं गलत हो सकता है क्योंकि मैं इसके बारे में बहुत अच्छी तरह से सूचित नहीं हूं।
गिगी

@ChrisMarisic, इसलिए, जो आप कह रहे हैं कि आप स्रोत से लाइव कोड बनाने के लिए रोज़लिन का उपयोग कर सकते हैं, न कि एक बाइनरी से जो चल रहा है। और आप अभी भी रोसलिन का उपयोग स्रोत को बायनेरिज़ में बदलने के लिए कर रहे हैं जो रोसलिन का उपयोग थ्रो बिन्रीज़ को बदलने के लिए नहीं करता है। यदि आप रनटाइम के दौरान रोसलिन का अचानक उपयोग नहीं कर सकते, तो आप कभी भी किसी कोड का संकलन नहीं कर सकते।
पाउलो मोर्गादो

जवाबों:


119

हाँ। nameof()संकलन-समय पर मूल्यांकन किया जाता है। चश्मा के नवीनतम संस्करण को देखते हुए:

नेमोफ अभिव्यक्ति एक स्थिर है। सभी मामलों में, एक स्ट्रिंग का उत्पादन करने के लिए नामोफ़ (...) का संकलन-समय पर मूल्यांकन किया जाता है । इसके तर्क का मूल्यांकन रनटाइम पर नहीं किया जाता है, और इसे अगम्य कोड माना जाता है (हालांकि यह "अगम्य कोड" चेतावनी का उत्सर्जन नहीं करता है)।

से nameof ऑपरेटर - v5

आप इस TryRoslyn उदाहरण के साथ देख सकते हैं जहां यह:

public class Foo
{
    public void Bar()
    {
        Console.WriteLine(nameof(Foo));
    }
}

इसमें संकलित और विघटित किया गया है:

public class Foo
{
    public void Bar()
    {
        Console.WriteLine("Foo");
    }
}

इसका रन-टाइम समतुल्य है:

public class Foo
{
    public void Bar()
    {
        Console.WriteLine(typeof(Foo).Name);
    }
}

जैसा कि टिप्पणियों में उल्लेख किया गया था, इसका मतलब है कि जब आप nameofसामान्य प्रकार में पैरामीटर का उपयोग करते हैं, तो केवल टाइप पैरामीटर्स के नाम के बजाय वास्तविक डायनामिक प्रकार का नाम टाइप पैरामीटर के रूप में उपयोग करने की अपेक्षा न करें। तो यह:

public class Foo
{
    public void Bar<T>()
    {
        Console.WriteLine(nameof(T));
    }
}

यह बन जाएगा :

public class Foo
{
    public void Bar<T>()
    {
        Console.WriteLine("T");
    }
}

यहाँ "संकलन-समय" क्या है? MSIL का संकलन या देशी कोड का संकलन?
user541686

6
@ मेहरदाद C # कंपाइलर IL उत्पन्न करता है।
i3arnon

3
त्वरित प्रश्न, क्या मैं एक स्विच मामले में नेमॉफ का उपयोग कर सकता हूं?
वर्तनी

2
@Spell Yes
i3arnon

58

मैं @ I3arnon द्वारा प्रदान किए गए उत्तर को एक प्रमाण के साथ समृद्ध करना चाहता था कि इसका संकलन-समय पर मूल्यांकन किया जाता है।

चलो मान लेते हैं कि मैं nameofऑपरेटर का उपयोग करके कंसोल में एक चर का नाम प्रिंट करना चाहता हूं :

 var firstname = "Gigi";
 var varname = nameof(firstname);
 Console.WriteLine(varname); // Prints "firstname" to the console

जब आप एमएसआईएल उत्पन्न की जाँच करते हैं, तो आप देखेंगे कि यह एक स्ट्रिंग घोषणा के बराबर है क्योंकि एक स्ट्रिंग के लिए एक ऑब्जेक्ट संदर्भ ldstrऑपरेटर का उपयोग करके स्टैक को धकेल दिया जाता है :

IL_0001: ldstr "Gigi"
IL_0006: stloc.0
IL_0007: ldstr "firstname"
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: call void [mscorlib]System.Console::WriteLine(string)

आप देखेंगे कि फर्स्टनाम स्ट्रिंग घोषित करना और nameofऑपरेटर का उपयोग करना MSIL में एक ही कोड उत्पन्न करता है, जिसका अर्थ nameofहै कि स्ट्रिंग वेरिएबल घोषित करने में उतना ही कुशल है।


4
यदि MSIL को स्रोत कोड में विघटित कर दिया जाता है, तो यह समझने में कितना आसान होगा कि डिकंपाइलर एक nameofऑपरेटर है, न कि एक सादा हार्डकोडेड स्ट्रिंग?
ADTC

11
यह एक अच्छा सवाल है! आप इसे एसओ पर एक नए प्रश्न के रूप में पोस्ट कर सकते हैं यदि आप एक विस्तृत विवरण प्राप्त करना चाहते हैं :) .. हालांकि संक्षिप्त जवाब यह है कि डिकंपाइलर यह पता लगाने में सक्षम नहीं होगा कि यह एक नाम ऑपरेटर था, लेकिन इसके बजाय एक स्ट्रिंग शाब्दिक का उपयोग करेगा । मैंने सत्यापित किया है कि ILSpy और परावर्तक के साथ मामला है।
फारिस ज़सीना


2
यह दिलचस्प है। शायद decompiler वर्तमान संदर्भ (विधि / संपत्ति / आदि आप में हैं का नाम) के खिलाफ स्ट्रिंग की जांच कर सकता है। फिर भी, इसके 100% विश्वसनीय होने का कोई तरीका नहीं है - आपने एक हार्डकोड स्ट्रिंग का उपयोग किया होगा।
गीगी

2
हालांकि मैं मानता हूं कि आप यह नहीं जान सकते कि संकलन के बाद यह एक नाम है या नहीं, मुझे ऐसा कोई संकेत नहीं दिखता है जो ILSpy या परावर्तक C # 6 को अभी तक समर्थन करता है। अगर ऐसा है, तो आप इसे @TheMinister
Millie Smith
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.