इस व्यवहार को समझने के लिए आपको दो बातें जानने की जरूरत है।
- सभी प्रतिनिधि से निकलते हैं
System.Delegate
, लेकिन विभिन्न प्रतिनिधियों के अलग-अलग प्रकार होते हैं और इसलिए उन्हें एक-दूसरे को नहीं सौंपा जा सकता है।
- सी # भाषा एक प्रतिनिधि को एक विधि या लैम्ब्डा निर्दिष्ट करने के लिए विशेष हैंडलिंग प्रदान करती है ।
क्योंकि अलग-अलग प्रतिनिधियों के अलग-अलग प्रकार होते हैं, इसका मतलब है कि आप एक प्रकार के प्रतिनिधि को दूसरे को नहीं सौंप सकते हैं।
उदाहरण के लिए, दिया गया:
delegate void test1(int i);
delegate void test2(int i);
फिर:
test1 a = Console.WriteLine; // Using special delegate initialisation handling.
test2 b = a; // Using normal assignment, therefore does not compile.
उपरोक्त पहली पंक्ति ओके को संकलित करती है क्योंकि यह लैम्बडा या किसी प्रतिनिधि को एक विधि निर्दिष्ट करने के लिए विशेष हैंडलिंग का उपयोग कर रही है।
वास्तव में, यह लाइन संकलक द्वारा इस तरह से फिर से लिखी गई है:
test1 a = new test1(Console.WriteLine);
ऊपर की दूसरी पंक्ति संकलित नहीं करती है क्योंकि यह एक प्रकार के उदाहरण को दूसरे असंगत प्रकार के रूप में निर्दिष्ट करने का प्रयास कर रही है।
जहाँ तक प्रकारों में जाते हैं, वहाँ कोई संगत कार्य नहीं होता है test1
और test2
क्योंकि वे विभिन्न प्रकार के होते हैं।
यदि इसके बारे में सोचने में मदद मिलती है, तो इस वर्ग पदानुक्रम पर विचार करें:
class Base
{
}
class Test1 : Base
{
}
class Test2 : Base
{
}
निम्नलिखित कोड संकलन नहीं करेगा, भले ही Test1
और Test2
उसी आधार वर्ग से प्राप्त हो:
Test1 test1 = new Test1();
Test2 test2 = test1; // Compile error.
यह बताता है कि आप एक प्रतिनिधि प्रकार को दूसरे को क्यों नहीं सौंप सकते हैं। वह सामान्य सी # भाषा है।
हालाँकि, महत्वपूर्ण बात यह समझना है कि आपको एक विधि या लैम्बडा को एक संगत प्रतिनिधि को सौंपने की अनुमति क्यों है। जैसा कि ऊपर उल्लेख किया गया है, यह प्रतिनिधियों के लिए C # भाषा समर्थन का हिस्सा है।
तो अंत में अपने प्रश्न का उत्तर दें:
जब आप उपयोग Invoke()
करते हैं, तो आप एक असंगत प्रकार को निर्दिष्ट करने की कोशिश करने के बजाय एक प्रतिनिधि को विधियों या लैम्ब्डा निर्दिष्ट करने के लिए विशेष C # भाषा हैंडलिंग का उपयोग करके प्रतिनिधि को एक METHOD कॉल प्रदान कर रहे हैं - इसलिए यह ठीक संकलित करता है।
पूरी तरह से स्पष्ट होने के लिए, कोड जो आपके ओपी में संकलित है:
public test Success()
{
Func<int, int> f = x => x;
return f.Invoke; // <- code successfully compiled
}
वास्तव में वैचारिक रूप से कुछ इस तरह से परिवर्तित किया जाता है:
public test Success()
{
Func<int, int> f = x => x;
return new test(f.Invoke);
}
जबकि असफल कोड दो असंगत प्रकारों के बीच असाइन करने का प्रयास कर रहा है:
public test Fail()
{
Func<int, int> f = x => x;
return f; // Attempting to assign one delegate type to another: Fails
}