C # में एक विधि समूह क्या है?


351

मुझे अक्सर इस तरह के मामलों में "विधि समूह से 'स्ट्रिंग' में परिवर्तित नहीं कर सकते हैं जैसे एक त्रुटि का सामना करना पड़ा है:

var list = new List<string>();
// ... snip
list.Add(someObject.ToString);

निश्चित रूप से अंतिम पंक्ति में एक टाइपो था क्योंकि मैं बाद में मंगलाचरण को भूल गया था ToString। सही रूप होगा:

var list = new List<string>();
// ... snip
list.Add(someObject.ToString()); // <- notice the parentheses

हालाँकि मुझे आश्चर्य हुआ कि एक विधि समूह क्या है। Google बहुत मदद नहीं कर रहा है और न ही MSDN


62
सी # 3.0 विनिर्देश की धारा 7.1 "विधि समूह" को परिभाषित करती है।
एरिक लिपर्ट

2
मैंने इस त्रुटि को पढ़ा क्योंकि अब आप किसी विधि को कॉल करते समय कोष्ठक से चूक गए
नीको 23:16

2
यदि आपके पास एक उपयुक्त प्रतिनिधि प्रकार की सूची होती, जैसे कि var list = new List<Func<string>>();, तब विधि समूह प्रयोग करने योग्य होता, और list.Add(someObject.ToString);काम करता।
जेपी स्टिग नील्सन

जवाबों:


332

एक विधि समूह एक के लिए नाम है तरीकों में से सेट सिद्धांत में यानी - (है कि हो सकता है सिर्फ एक) ToStringविधि कई भार के (प्लस किसी भी विस्तार विधि) हो सकता है: ToString(), ToString(string format), आदि - इसलिए ToStringअपने आप में एक "विधि समूह" है।

यह आमतौर पर एक विधि समूह को एक (टाइप) प्रतिनिधि को ओवरलोड रिज़ॉल्यूशन का उपयोग करके परिवर्तित कर सकता है - लेकिन एक स्ट्रिंग आदि के लिए नहीं; इसका कोई मतलब नहीं है।

एक बार जब आप कोष्ठक जोड़ते हैं, फिर से; ओवरलोड रिज़ॉल्यूशन किक करता है और आपने एक विधि कॉल को स्पष्ट रूप से पहचान लिया है।


6
विधि समूह के विशिष्ट उपयोग क्या होंगे? चूंकि (इसलिए मैं समझता हूं) इसका एक ही नाम है पैरामीटर गणना और / या प्रकार भिन्न होंगे। इसलिए आप समूह का उपयोग करते हुए विधि समूह से एक से अधिक विधि नहीं ला सकते हैं।
आंद्रेई रोनेया

32
यह पूरी तरह से "मुझे पता है कि विधि का नाम क्या है, लेकिन मैं हस्ताक्षर नहीं जानता" के लिए एक संकलक शब्द है; इसका रनटाइम पर कोई अस्तित्व नहीं है। AFAIK, स्वयं (कोई कोष्ठक आदि) द्वारा विधि-समूह का एकमात्र उपयोग प्रतिनिधि निर्माण के दौरान है।
मार्क Gravell

20
ECMA 334v4 §14.1: एक विधि समूह का उपयोग एक मंगलाचरण-अभिव्यक्ति (.514.5.5) में किया जा सकता है, जिसका उपयोग एक प्रतिनिधि-निर्माण-अभिव्यक्ति (§14.5.10.3) में किया जाता है, या इसे एक संगत प्रतिनिधि प्रकार में बदल दिया जाता है। किसी अन्य संदर्भ में, विधि समूह के रूप में वर्गीकृत एक अभिव्यक्ति एक संकलन-समय त्रुटि का कारण बनती है।
मार्क ग्रेवल

1
विधि समूहों के लिए सहसंयोजक और विरोधाभासी समर्थन प्रतिनिधि प्रकार के साथ विधि हस्ताक्षर मिलान के लिए अनुमति देता है। यह आपको प्रतिनिधियों को न केवल उन विधियों को सौंपने में सक्षम बनाता है जिनमें मिलान वाले हस्ताक्षर होते हैं, बल्कि वे तरीके भी होते हैं जो अधिक व्युत्पन्न प्रकार (कोवरियन) लौटाते हैं या ऐसे पैरामीटर को स्वीकार करते हैं जिनके प्रतिनिधि प्रकार द्वारा निर्दिष्ट की तुलना में कम व्युत्पन्न प्रकार (विपरीत) होते हैं। अधिक जानकारी के लिए, डेलिगेट्स में Carians देखें (C #) और Delegates में Variance का उपयोग करें (C #)।
user2211290

162

इसके अलावा, यदि आप LINQ का उपयोग कर रहे हैं, तो आप स्पष्ट रूप से कुछ ऐसा कर सकते हैं myList.Select(methodGroup)

इसलिए, उदाहरण के लिए, मेरे पास:

private string DoSomethingToMyString(string input)
{
    // blah
}

इसके बजाय स्पष्ट रूप से चर का उपयोग इस तरह से करने के लिए:

public List<string> GetStringStuff()
{
    return something.getStringsFromSomewhere.Select(str => DoSomethingToMyString(str));
}

मैं सिर्फ var का नाम छोड़ सकता हूं:

public List<string> GetStringStuff()
{
    return something.getStringsFromSomewhere.Select(DoSomethingToMyString);
}

112
एक ReSharper की सिफारिश ने मुझे विधि समूह की खोज करने के लिए प्रेरित किया। यही वह है जो रेस्परर ने मेरे एक लाइनक एक्सप्रेशन को पूरा किया।
a_hardin

50
@a_hardin: ReSharper FTW! मैंने LINQ को Resharper के लिए धन्यवाद के बारे में बहुत कुछ सीखा।
जेसन डाउन

3
"अधिक स्पष्ट" संस्करण केवल एक अनिवार्य रूप से बेकार आवरण विधि बना रहा है। अनाम आवरण विधि और DoSomethingToMyString दोनों एक स्ट्रिंग लेते हैं और एक स्ट्रिंग लौटाते हैं। "Str => [...] (str)" अक्षर सिर्फ cruft हैं जो संकलक उम्मीद से दूर का अनुकूलन करते हैं।
ग्रेल्ट

6
संकलक कुछ भी अनुकूलन नहीं करता है। ILDASM का उपयोग करते हुए, आप देखते हैं कि स्पष्ट संस्करण एक अनाम विधि (लैंबडा कार्यान्वयन) बनाता है और इसे चयन () में पास करता है। निहित संस्करण सीधे DoSomethingToMyString गुजरता है।
रॉल्फ

14
मुझे return flag == true ? true : false(फेसपालम) याद दिलाता है ।
एरिक

24

आप एक प्रतिनिधि में एक विधि समूह कास्ट कर सकते हैं ।

प्रतिनिधि हस्ताक्षर समूह से बाहर 1 विधि का चयन करता है।

यह उदाहरण ToString()एक स्ट्रिंग पैरामीटर लेने वाले अधिभार को उठाता है :

Func<string,string> fn = 123.ToString;
Console.WriteLine(fn("00000000"));

यह उदाहरण ToString()अधिभार लेता है जो कोई पैरामीटर नहीं लेता है:

Func<string> fn = 123.ToString;
Console.WriteLine(fn());

21

आपके MSDN खोज में पहला परिणाम कहा गया है:

विधि समूह, आह्वान करने के लिए एक विधि की पहचान करता है या अतिभारित विधियों का समुच्चय होता है जिसमें से आह्वान करने के लिए एक विशिष्ट विधि का चयन किया जाता है

मेरी समझ यह है कि मूल रूप से क्योंकि जब आप सिर्फ लिखते हैं someInteger.ToString, तो यह निम्नलिखित हो सकता है:

Int32.ToString(IFormatProvider) 

या यह उल्लेख कर सकते हैं:

Int32.ToString()

इसलिए इसे एक विधि समूह कहा जाता है।


18

ToStringसमारोह में कई भार के है - विधि समूह है कि समारोह के लिए सभी विभिन्न भार के से मिलकर समूह होगा।


2
हां, और मुद्दा यह है कि एक विधि समूह एक संकलन-समय निर्माण है। कंपाइलर संदर्भ विधि के अनुसार एक विधि अधिभार चुनता है जहां संदेश समूह का उपयोग किया जाता है। उदाहरण के लिए: आप "var x = Foo;" नहीं लिख सकते (जहां फू एक विधि समूह है), कंपाइलर इसे अस्वीकार कर देता है, भले ही एक ही अधिभार हो।
रॉल्फ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.