Nameof का उद्देश्य क्या है?


263

संस्करण 6.0 को एक नई सुविधा मिली nameof , लेकिन मैं इसका उद्देश्य नहीं समझ सकता, क्योंकि यह सिर्फ चर नाम लेता है और संकलन के लिए इसे स्ट्रिंग में बदल देता है।

मैंने सोचा कि इसका उपयोग करने के दौरान कुछ उद्देश्य हो सकता है, <T>लेकिन जब मैं nameof(T)इसे करने की कोशिश करता हूं तो बस Tइस्तेमाल किए गए प्रकार के बजाय मुझे प्रिंट करता है ।

उद्देश्य पर कोई विचार?



28
Tइससे पहले ऐसा करने का कोई तरीका नहीं था । पहले इस्तेमाल किए गए प्रकार को प्राप्त करने का एक तरीका था।
जॉन हैना

शुरू में यह ओवरकिल की तरह लग रहा था और मैं अभी भी इसे इस्तेमाल करने के लिए एक आकर्षक कारण नहीं देख रहा हूं। शायद एक एमवीसी उदाहरण?
कोरी एलिक्स

15
निश्चित रूप से उपयोगी है जब नाम को फिर से नाम / नाम बदलना nameof। टाइपो को रोकने में भी मदद करता है।
bvj

4
नेमॉफ का आधिकारिक दस्तावेज यहां स्थानांतरित हो गया है: docs.microsoft.com/en-us/dotnet/csharp/language-reference/… - यह उन महत्वपूर्ण उपयोग मामलों को भी सूचीबद्ध करता है जो प्रश्न का बहुत अच्छा जवाब देते हैं।
मार्कस

जवाबों:


322

उन मामलों के बारे में जो आप एक संपत्ति के नाम का पुन: उपयोग करना चाहते हैं, उदाहरण के लिए जब एक संपत्ति के नाम के आधार पर अपवाद फेंकते हैं, या एक PropertyChangedघटना को संभालते हैं । ऐसे कई मामले हैं जहाँ आप संपत्ति का नाम रखना चाहेंगे।

इस उदाहरण को लें:

switch (e.PropertyName)
{
    case nameof(SomeProperty):
    { break; }

    // opposed to
    case "SomeOtherProperty":
    { break; }
}

पहले मामले में, नाम बदलकर SomeProperty बदलने से संपत्ति का नाम भी बदल जाएगा, या यह संकलन को तोड़ देगा। आखिरी मामला नहीं है।

यह आपके कोड को संकलित और बग मुक्त (सॉर्ट-ऑफ) रखने के लिए एक बहुत ही उपयोगी तरीका है।

( एरिक लिपर्ट का एक बहुत अच्छा लेखinfoof इसे क्यों नहीं बनाया, जबकि nameofकिया)


1
मैं इस बात को समझता हूं, सिर्फ नाम जोड़ने से जब फेरबदल होता है, तो निश्चित रूप से पता चलता है कि अगर वीएस की समान कार्यक्षमता है, तो स्ट्रिंग्स को बदल देता है।
ऐश बर्लाज़ेंको

7
यह है। लेकिन दोनों Resharper और VS उदाहरण के लिए परियोजनाओं पर काम नहीं करते हैं। यह करता है। वास्तव में, यह बेहतर उपाय है।
पैट्रिक हॉफमैन

49
एक अन्य सामान्य उपयोग का मामला एमवीसी का उपयोग कर रहा है nameofऔर हार्ड-कोडेड स्ट्रिंग के बजाय एक्शन का नाम है।
आरजे कटहबर्टसन

2
@sotn मुझे यकीन नहीं है कि मैं समझता हूं कि आप क्या पूछ रहे हैं। इसका उपयोग करने से आपको कुछ भी नहीं रोक रहा है public class MyController { public ActionResult Index() { return View(nameof(Index)); } }- और आप nameofगैर-स्थैतिक सदस्यों का उपयोग कर सकते हैं (उदाहरण के लिए आप nameof(MyController.Index)ऊपर के वर्ग का उपयोग करके कॉल कर सकते हैं और यह "इंडेक्स" का उत्सर्जन करेगा)। Msdn.microsoft.com/en-us/library/…
RJ Cuthbertson

2
मैं यह नहीं देखता कि विशेष क्यों है। चर नाम हमेशा समान होते हैं, है ना? आपके पास कोई उदाहरण है या नहीं, परिवर्तनशील नाम @sotn नहीं बदलेंगे
पैट्रिक हॉफमैन

176

यह वास्तव में ArgumentExceptionऔर इसके डेरिवेटिव के लिए उपयोगी है :

public string DoSomething(string input) 
{
    if(input == null) 
    {
        throw new ArgumentNullException(nameof(input));
    }
    ...

अब यदि कोई inputपैरामीटर के नाम को रिफ्लेक्टर करता है तो अपवाद को भी अद्यतित रखा जाएगा।

यह कुछ स्थानों पर भी उपयोगी है जहां पहले प्रतिबिंब का उपयोग गुणों या मापदंडों के नाम प्राप्त करने के लिए किया जाना था।

आपके उदाहरण nameof(T)में टाइप पैरामीटर का नाम मिलता है - यह उपयोगी भी हो सकता है:

throw new ArgumentException(nameof(T), $"Type {typeof(T)} does not support this method.");

nameofएनम का एक और उपयोग है - आमतौर पर यदि आप एक एनुम का स्ट्रिंग नाम चाहते हैं जो आप उपयोग करते हैं .ToString():

enum MyEnum { ... FooBar = 7 ... }

Console.WriteLine(MyEnum.FooBar.ToString());

> "FooBar"

यह वास्तव में .net के रूप में अपेक्षाकृत धीमी गति से चलता है। एनम मान (यानी 7) रखता है और रन टाइम पर नाम पाता है।

इसके बजाय उपयोग करें nameof:

Console.WriteLine(nameof(MyEnum.FooBar))

> "FooBar"

अब .Net संकलन समय पर एक स्ट्रिंग के साथ एनम नाम की जगह लेता है।


फिर भी एक और उपयोग चीजों INotifyPropertyChangedऔर लॉगिंग के लिए है - दोनों ही मामलों में आप उस सदस्य का नाम चाहते हैं जिसे आप किसी अन्य विधि से पारित करने के लिए बुला रहे हैं:

// Property with notify of change
public int Foo
{
    get { return this.foo; }
    set
    {
        this.foo = value;
        PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.Foo));
    }
}

या ...

// Write a log, audit or trace for the method called
void DoSomething(... params ...)
{
    Log(nameof(DoSomething), "Message....");
}

9
और आपने एक और अच्छा फीचर डाला है: स्ट्रिंग इंटरपोलेशन!
पैट्रिक हॉफमैन

1
@PatrickHofman और typeof(T), जो संकलन-समय की चीनी का एक और टुकड़ा है जो समान परिस्थितियों में उपयोगी है :-)
कीथ

1
एक चीज जो मुझे याद आ रही है वह कुछ इस तरह है nameofthismethod। आप इसका उपयोग कर सकते हैं Log.Error($"Error in {nameof(DoSomething)}...")लेकिन यदि आप इसे अन्य तरीकों से कॉपी-पेस्ट करते हैं तो आप ध्यान नहीं देंगे कि यह अभी भी संदर्भित है DoSomething। इसलिए जब यह स्थानीय चर या मापदंडों के साथ पूरी तरह से काम कर रहा है, तो विधि-नाम एक समस्या है।
टिम श्मेल्टर

3
क्या आप जानते हैं कि मौजूद होने पर विशेषता का nameOfउपयोग करेंगे [DisplayName]या नहीं? उदाहरण के enumलिए मैं [DisplayName]एमवीसी परियोजनाओं के साथ अक्सर उपयोग करता हूं
ल्यूक टी ओ'ब्रायन

2
@AaronLS हाँ, यह काफी विशिष्ट है और ऐसा कुछ नहीं है जिसका आप अक्सर उपयोग करते हों। हालांकि, throw newयह एक पूरी तरह से अन्य विरोधी पैटर्न है - मैं catchजूनियर देवों के साथ एक आम समस्या होने के लिए अति-उपयोग करता हूं क्योंकि यह समस्या को ठीक करने जैसा लगता है (जब ज्यादातर समय यह इसे छिपा रहा होता है)।
कीथ

26

एक और उपयोग-मामला जहां nameofC # 6.0 की सुविधा काम में आती है - एक लाइब्रेरी पर विचार करें जैसे डैपर जो DB रिट्रीवल को बहुत आसान बनाता है। यद्यपि यह एक महान पुस्तकालय है, आपको क्वेरी के भीतर संपत्ति / फ़ील्ड नामों को हार्डकोड करने की आवश्यकता है। इसका मतलब यह है कि यदि आप अपनी संपत्ति / क्षेत्र का नाम बदलने का निर्णय लेते हैं, तो उच्च संभावनाएं हैं कि आप नए फ़ील्ड नामों का उपयोग करने के लिए क्वेरी को अपडेट करना भूल जाएंगे। स्ट्रिंग प्रक्षेप और nameofसुविधाओं के साथ, कोड बनाए रखना और टाइप करना बहुत आसान हो जाता है।

लिंक में दिए गए उदाहरण से

बिना नाम के

var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });

नाम के साथ

var dog = connection.Query<Dog>($"select {nameof(Dog.Age)} = @Age, {nameof(Dog.Id)} = @Id", new { Age = (int?)null, Id = guid });

3
मैं डैपर से प्यार करता हूं और मुझे वास्तव में स्ट्रिंग इंटरप्रेन्योरशिप पसंद है, लेकिन आईएमओ यह बहुत बदसूरत दिखता है। इस तरह के बदसूरत प्रश्नों की तुलना में एक कॉलम का नाम बदलकर क्वेरी को तोड़ने का जोखिम बहुत कम लगता है। पहली नजर में मैं कहूँगा कि मैं EF LINQ प्रश्नों को लिखना पसंद करता हूँ, या [TableName] जैसे एक सम्मलेन का अनुसरण करता हूँ। [ColumnName] जहाँ मुझे अपने प्रश्नों की आवश्यकता पड़ने पर आसानी से मिल / बदल सकती है।
०४:१४ बजे

@ ड्रीज़िन मैं ऐसे प्रश्नों (और चिंताओं को अलग करने के लिए) को रोकने के लिए डैपर फ्लुएंटफ़ायर का उपयोग करता हूं
mamuesstack

21

आपका प्रश्न पहले से ही उद्देश्य को व्यक्त करता है। आपको यह देखना होगा कि अपवादों को लॉग इन करना या फेंकना उपयोगी हो सकता है।

उदाहरण के लिए।

public void DoStuff(object input)
{
    if (input == null)
    {
        throw new ArgumentNullException(nameof(input));
    }
}

यह अच्छा है, अगर मैं चर का नाम बदलता हूं तो कोड बदलेगा या गलत संदेश के साथ अपवाद लौटाएगा


बेशक, उपयोग इस सरल स्थिति तक सीमित नहीं हैं। nameofजब भी किसी चर या संपत्ति के नाम को कोड करना उपयोगी होगा, तब आप इसका उपयोग कर सकते हैं।

जब आप विभिन्न बाध्यकारी और प्रतिबिंब स्थितियों पर विचार करते हैं तो उपयोग कई गुना होता है। यह एक उत्कृष्ट तरीका है जो समय संकलित करने के लिए समय त्रुटियों को चला रहे थे।


6
@atikot: लेकिन फिर, यदि आप वैरिएबल का नाम बदलते हैं, तो संकलक ध्यान नहीं देगा कि स्ट्रिंग किसी भी अधिक मेल नहीं खाती है।
या मैपर

1
मैं वास्तव में पुनर्खरीद का उपयोग करता हूं जो इसे ध्यान में रखता है, लेकिन मैं आपकी बात देखता हूं।
एटिकॉट

4
@atikot, इसलिए मैं करता हूं, लेकिन Resharper केवल एक चेतावनी उत्पन्न करता है, न कि संकलक त्रुटि। एक निश्चितता और अच्छी सलाह के बीच अंतर है।
जोडरेल

1
@atikot, और, Resharper लॉगिंग संदेशों की जाँच नहीं करता है
Jodrell

2
@Jodrell: और, मुझे संदेह है, यह विभिन्न अन्य उपयोगों की जांच नहीं करता है, या तो - कोड-पीछे में बनाए गए WPF बाइंडिंग के बारे में कैसे, कस्टम OnPropertyChangedतरीके (जो सीधे संपत्ति के नाम को स्वीकार करते हैं PropertyChangedEventArgs), या किसी विशेष को देखने के लिए प्रतिबिंब को कॉल करते हैं। सदस्य या प्रकार?
या मैपर

13

सबसे आम उपयोग मामला मैं सोच सकता हूं जब INotifyPropertyChangedइंटरफ़ेस के साथ काम कर रहा है। (मूल रूप से WPF और बाइंडिंग से जुड़ी हर चीज इस इंटरफेस का उपयोग करती है)

इस उदाहरण पर एक नज़र डालें:

public class Model : INotifyPropertyChanged
{
    // From the INotifyPropertyChanged interface
    public event PropertyChangedEventHandler PropertyChanged;

    private string foo;
    public String Foo
    {
        get { return this.foo; }
        set
        {
            this.foo = value;
            // Old code:
            PropertyChanged(this, new PropertyChangedEventArgs("Foo"));

            // New Code:
            PropertyChanged(this, new PropertyChangedEventArgs(nameof(Foo)));           
        }
    }
}

जैसा कि आप पुराने तरीके से देख सकते हैं कि हमें यह बताने के लिए एक स्ट्रिंग पास करनी होगी कि कौन सी संपत्ति बदल गई है। साथ nameofहम सीधे संपत्ति के नाम का उपयोग कर सकते हैं। यह एक बड़ी बात नहीं लग सकती है। लेकिन छवि तब होती है जब कोई संपत्ति का नाम बदलता है Foo। एक स्ट्रिंग का उपयोग करते समय बाध्यकारी काम करना बंद कर देगा, लेकिन संकलक आपको चेतावनी नहीं देगा। नाम का उपयोग करते समय आपको एक संकलक त्रुटि मिलती है कि नाम के साथ कोई संपत्ति / तर्क नहीं है Foo

ध्यान दें कि कुछ फ्रेमवर्क संपत्ति के नाम को प्राप्त करने के लिए कुछ प्रतिबिंब जादू का उपयोग करते हैं, लेकिन अब हमारे पास इसका नाम है यह अब पेचीदा नहीं है


5
जब तक यह एक वैध दृष्टिकोण है, एक अधिक सुविधाजनक (और डीआरवाई) दृष्टिकोण [CallerMemberName]इस घटना को बढ़ाने के लिए एक नई विधि के परम पर विशेषता का उपयोग करना है ।
ड्रू नॉक्स

1
मैं मानता हूं कि CallerMemberName भी अच्छा है, लेकिन इसका एक अलग उपयोग मामला है, क्योंकि (जैसा कि आपने कहा) आप इसे केवल विधियों में उपयोग कर सकते हैं। DRY के लिए, मुझे यकीन नहीं है कि अगर इससे [CallerMemberName]string x = nullबेहतर है nameof(Property)। आप कह सकते हैं कि संपत्ति का नाम दो बार उपयोग किया जाता है, लेकिन मूल रूप से एक फ़ंक्शन को दिए गए तर्क। नहीं सच में क्या मतलब है DRY मुझे लगता है :)।
रॉय टी।

वास्तव में आप इसे गुणों में उपयोग कर सकते हैं। वे सदस्य भी हैं। इससे अधिक लाभ nameofयह है कि प्रॉपर्टी सेटर को कॉपी / पेस्ट बग की संभावना को समाप्त करते हुए, संपत्ति का नाम बिल्कुल भी निर्दिष्ट नहीं करना चाहिए।
ड्रू नोक जूल

4
यह 'के लिए एक साथ बेहतर' स्थिति है INotifyPropertyChanged, [CallerMemberNameAttribute]परिवर्तन की अधिसूचना को संपत्ति सेटर से सफाई से उठाने की nameofअनुमति देता है , जबकि सिंटैक्स आपके कोड में एक अलग स्थान से सफाई अधिसूचना को साफ करने की अनुमति देता है।
एंड्रयू हैनॉन

9

अधिकांश सामान्य उपयोग इनपुट सत्यापन में होंगे, जैसे कि

//Currently
void Foo(string par) {
   if (par == null) throw new ArgumentNullException("par");
}

//C# 6 nameof
void Foo(string par) {
   if (par == null) throw new ArgumentNullException(nameof(par));
}

पहले मामले में, यदि आप पैरा पैरा के नाम को बदलने की विधि को रिफ्लेक्टर करते हैं, तो आप शायद इसे तर्क में बदलना भूल जाएंगे । Nameof के साथ आपको उस बारे में चिंता करने की ज़रूरत नहीं है।

यह भी देखें: nameof (C # और Visual Basic संदर्भ)


7

ASP.NET Core MVC प्रोजेक्ट नियंत्रक में किसी क्रिया को संदर्भित करने के nameofलिए AccountController.csऔर उसके ManageController.csसाथ RedirectToActionविधि का उपयोग करता है ।

उदाहरण:

return RedirectToAction(nameof(HomeController.Index), "Home");

यह करने के लिए अनुवाद:

return RedirectToAction("Index", "Home");

और 'होम' कंट्रोलर में उपयोगकर्ता को 'इंडेक्स' की कार्रवाई तक ले जाता है, अर्थात /Home/Index


क्यों नहीं पूरे-हॉग और उपयोग करें return RedirectToAction(nameof(HomeController.Index), nameof(HomeController).Substring(nameof(HomeController),0,nameof(HomeController).Length-"Controller".Length));?
सनकैट २२

@ Suncat2000 क्योंकि उन चीजों में से एक संकलन में किया जाता है और दूसरा नहीं है? :)
डायनेडो

6

जैसा कि दूसरों ने पहले ही बताया है, nameofऑपरेटर उस नाम को सम्मिलित करता है जो तत्व सोर्सकोड में दिया गया था।

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

static void Main(string[] args)
{
    Console.WriteLine(nameof(args));
    Console.WriteLine("regular text");
}

// striped nops from the listing
IL_0001 ldstr args
IL_0006 call System.Void System.Console::WriteLine(System.String)
IL_000C ldstr regular text
IL_0011 call System.Void System.Console::WriteLine(System.String)
IL_0017 ret

हालाँकि, यह एक खामी हो सकती है यदि आप अपने सॉफ़्टवेयर को बाधित करने की योजना बनाते हैं। आक्षेप के बाद एम्बेडेड स्ट्रिंग अब तत्व के नाम से मेल नहीं खा सकती है। इस पाठ पर निर्भर रहने वाले तंत्र टूट जाएंगे। उस के लिए उदाहरण, जिसमें शामिल हैं, लेकिन सीमित नहीं हैं: प्रतिबिंब, NotifyPropertyChanged ...

रनटाइम के दौरान नाम का निर्धारण करने में कुछ प्रदर्शन की लागत होती है, लेकिन ओफिसकेशन के लिए सुरक्षित है। यदि आक्षेप की न तो आवश्यकता है और न ही योजना बनाई गई है, तो मैं nameofऑपरेटर का उपयोग करने की सलाह दूंगा।


5

इस बात पर विचार करें कि आप अपने कोड में एक चर का उपयोग करते हैं और चर का नाम प्राप्त करने की आवश्यकता है और इसे प्रिंट करने की अनुमति देता है, आपको इसका उपयोग करना चाहिए

int myVar = 10;
print("myVar" + " value is " + myVar.toString());

और फिर अगर कोई कोड को रिफ्लेक्टर करता है और "myVar" के लिए किसी अन्य नाम का उपयोग करता है, तो उसे आपके कोड में स्ट्रिंग मान के लिए देखना होगा और उसी के अनुसार इसे चेंज करना होगा।

इसके बजाय अगर आपके पास था

print(nameof(myVar) + " value is " + myVar.toString());

यह अपने आप रिफ्लेक्टर करने में मदद करेगा!


काश, एक विशेष चर-पैरामीटर सिंटैक्स होता, जो कि स्रोत कोड प्रतिनिधित्व Type,, और मान वाले प्रत्येक पैरामीटर के लिए टुपल्स की एक सरणी पास करता । यह अतिरेक को खत्म करने के लिए कोडिंग लॉगिंग विधियों के लिए संभव होगा।
सुपरकैट

5

MSDN लेख MVC रूटिंग (उदाहरण जो वास्तव में मेरे लिए अवधारणा पर क्लिक करता है) को कई अन्य लोगों के बीच सूचीबद्ध करता है। (स्वरूपित) विवरण पैराग्राफ पढ़ता है:

  • कोड में त्रुटियों की रिपोर्ट करते समय,
  • मॉडल-व्यू-कंट्रोलर (MVC) लिंक को हुक करना,
  • फायरिंग संपत्ति बदल घटनाओं, आदि;

आप अक्सर किसी विधि का स्ट्रिंग नाम कैप्चर करना चाहते हैं । नाम का उपयोग करने से परिभाषाओं का नाम बदलने पर आपके कोड को मान्य रखने में मदद मिलती है

इससे पहले कि आप परिभाषाओं को संदर्भित करने के लिए स्ट्रिंग शाब्दिक का उपयोग करें , जो कोड तत्वों का नाम बदलने के दौरान भंगुर है क्योंकि उपकरण इन स्ट्रिंग शाब्दिकों की जांच करना नहीं जानते हैं।

स्वीकृत / टॉप रेटेड उत्तर पहले से ही कई उत्कृष्ट ठोस उदाहरण देते हैं।


3

का उद्देश्य nameofऑपरेटर का कलाकृतियों का स्रोत नाम प्रदान करना है।

आमतौर पर स्रोत का नाम मेटाडेटा नाम के समान नाम है:

public void M(string p)
{
    if (p == null)
    {
        throw new ArgumentNullException(nameof(p));
    }
    ...
}

public int P
{
    get
    {
        return p;
    }
    set
    {
        p = value;
        NotifyPropertyChanged(nameof(P));
    }
}

लेकिन यह हमेशा मामला नहीं हो सकता है:

using i = System.Int32;
...
Console.WriteLine(nameof(i)); // prints "i"

या:

public static string Extension<T>(this T t)
{
    return nameof(T); returns "T"
}

संसाधनों के नामकरण के लिए मैं इसका एक उपयोग कर रहा हूं:

[Display(
    ResourceType = typeof(Resources),
    Name = nameof(Resources.Title_Name),
    ShortName = nameof(Resources.Title_ShortName),
    Description = nameof(Resources.Title_Description),
    Prompt = nameof(Resources.Title_Prompt))]

तथ्य यह है कि, इस मामले में, मुझे संसाधनों तक पहुंचने के लिए उत्पन्न संपत्तियों की आवश्यकता नहीं थी, लेकिन अब मेरे पास एक संकलन समय है कि संसाधन मौजूद हैं।


0

nameofकीवर्ड का उपयोग Bindingwpf में प्रोग्रामेटिक रूप से सेट करने के लिए है

सेट करने के लिए Bindingआपको Pathस्ट्रिंग के साथ सेट करना होगा, और nameofकीवर्ड के साथ , रिफ्लेक्टर विकल्प का उपयोग करना संभव है।

उदाहरण के लिए, यदि आपके पास IsEnableनिर्भरता संपत्ति है UserControlऔर आप इसे अपने IsEnableकुछ CheckBoxमें बाँधना चाहते हैं UserControl, तो आप इन दो कोडों का उपयोग कर सकते हैं:

CheckBox chk = new CheckBox();
Binding bnd = new Binding ("IsEnable") { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);

तथा

CheckBox chk = new CheckBox();
Binding bnd = new Binding (nameof (IsEnable)) { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);

यह स्पष्ट है कि पहला कोड रिफ्लेक्टर नहीं कर सकता लेकिन एक को सुरक्षित ...


0

पहले हम ऐसा कुछ प्रयोग कर रहे थे:

// Some form.
SetFieldReadOnly( () => Entity.UserName );
...
// Base form.
private void SetFieldReadOnly(Expression<Func<object>> property)
{
    var propName = GetPropNameFromExpr(property);
    SetFieldsReadOnly(propName);
}

private void SetFieldReadOnly(string propertyName)
{
    ...
}

कारण - संकलन समय सुरक्षा। कोई भी चुपचाप संपत्ति का नाम बदल सकता है और कोड तर्क तोड़ सकता है। अब हम nameof () का उपयोग कर सकते हैं।


0

इसका फायदा तब होता है जब आप ASP.Net MVC का उपयोग करते हैं। जब आप HTML इनपुट का उपयोग कुछ नियंत्रण बनाने के लिए करते हैं तो यह HTML इनपुट के नाम में संपत्ति के नाम का उपयोग करता है:

@Html.TextBoxFor(m => m.CanBeRenamed)

यह ऐसा कुछ बनाता है:

<input type="text" name="CanBeRenamed" />

तो अब, यदि आपको अपनी संपत्ति को मान्य करने की आवश्यकता है तो आप ऐसा कर सकते हैं:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
  if (IsNotValid(CanBeRenamed)) {
    yield return new ValidationResult(
      $"Property {nameof(CanBeRenamed)} is not valid",
      new [] { $"{nameof(CanBeRenamed)}" })
  }
}

यदि आप रिफ़ेक्टरिंग टूल का उपयोग करके संपत्ति का नाम बदल देते हैं, तो आपका सत्यापन नहीं टूटेगा।


0

nameofटैब पृष्ठों की जांच करने का एक अन्य उपयोग मामला है, सूचकांक की जांच करने के बजाय आप Nameनिम्न के अनुसार टैब की संपत्ति की जांच कर सकते हैं:

if(tabControl.SelectedTab.Name == nameof(tabSettings))
{
    // Do something
}

कम गन्दा :)


0

मुझे लगता है कि nameofमेरे अनुप्रयोगों में बहुत लंबे और जटिल एसक्यूएल बयानों की पठनीयता बढ़ जाती है। यह चर को तार के उस समुद्र से बाहर खड़ा करता है और यह पता लगाने के आपके काम को समाप्त कर देता है कि आपके SQL कथन में चर कहाँ उपयोग किए जाते हैं।

public bool IsFooAFoo(string foo, string bar)
{
    var aVeryLongAndComplexQuery = $@"SELECT yada, yada
    -- long query in here
    WHERE fooColumn = @{nameof(foo)}
    AND barColumn = @{nameof(bar)}
    -- long query here";


    SqlParameter[] parameters = {
        new SqlParameter(nameof(foo), SqlDBType.VarChar, 10){ Value = foo },
        new SqlParameter(nameof(bar), SqlDBType.VarChar, 10){ Value = bar },
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.