2010-07-19 4 views
8

तो काम पर मैं एक एपीआई का उपयोग कर रहा था जिसे हमने नहीं लिखा था, और विधियों में से एक ने एक प्रतिनिधि लिया। एक कारण या किसी अन्य कारण के लिए, यह विचार मेरे पास आया कि मेरे पास एक विस्तार विधि है जो हस्ताक्षर को फिट करती है, इसलिए मैं सोच रहा था कि यह काम करेगा या नहीं। मुझे यकीन था कि यह मेरे आश्चर्य के लिए ज्यादा नहीं होगा, ऐसा हुआ। मुझे का प्रदर्शन करने की अनुमति दें:किसी प्रतिनिधि को अपेक्षित विधि के लिए एक एक्सटेंशन विधि पास करना। यह कैसे काम करता है?

कहो मैं इन कक्षाओं में है:

public interface IMyInterface 
{ 

} 

public class MyClass : IMyInterface 
{ 

} 

public static class Extensions 
{ 
    public static string FuncMethod(this IMyInterface imy, int x) 
    { 
     return x.ToString(); 
    } 
} 
अब

चलो कहते हैं कि मैं एक विधि हस्ताक्षर कहीं है कि इस तरह दिखता है करते हैं:

private static void Method(Func<int, string> func) 
    { 

    } 

अब मेरी विस्तार विधि (तरह लग रहा है यह) हस्ताक्षर से मेल खाता है, लेकिन हम सभी जानते हैं कि विस्तार विधियां केवल धूम्रपान और दर्पण हैं, इसलिए वास्तव में हस्ताक्षर से मेल नहीं खाता है। फिर भी, मैं सुरक्षित रूप से ऐसा कर सकता हूं:

var instance = new MyClass(); 
Method(instance.FuncMethod); 

मेरा सवाल यह है कि यह कैसे काम करता है? इस स्वीकार्य बनाने के लिए संकलक मेरे लिए क्या उत्पन्न करता है। एक्सटेंशन विधि का वास्तविक हस्ताक्षर IMyInterface का उदाहरण लेता है, लेकिन Func ऐसा नहीं करता है कि दृश्यों के पीछे मेरे लिए क्या हो रहा है?

उत्तर

7

इंस्टेंस विधियों को छुपा this पैरामीटर लेने के रूप में लागू किया गया है।

जब आप किसी एक्सटेंशन विधि से इंस्टेंस प्रतिनिधि बनाते हैं, तो छुपा this पैरामीटर विधि को पहले सामान्य पैरामीटर के रूप में पास किया जाता है।

Note that this cannot be done with value types

0

मुझे नहीं पता कि संकलक इन परिदृश्यों को अनुमति देने के लिए क्या कर रहा है, लेकिन अपेक्षाएं उचित लगती हैं। शायद यह कोड नमूना अवधारणा को पकड़ने में मदद करेगा।

MyClass instance = new MyClass(); 
Func<int, string> f1 = instance.FuncMethod; 
Func<int, string> f2 = (i) => instance.FuncMethod(i); 
Func<int, string> f3 = (i) => Extensions.FuncMethod(instance, i); 
संबंधित मुद्दे