निश्चित रूप Func
से एक विशिष्ट प्रतिनिधि के बजाय उपयोग करने का वास्तविक कारण यह है कि सी # अलग-अलग घोषित प्रतिनिधियों को पूरी तरह से अलग प्रकार का मानता है।
भले ही Func<int, bool>
और Predicate<int>
दोनों के पास समान तर्क और वापसी प्रकार हैं, वे असाइनमेंट-संगत नहीं हैं। इसलिए यदि प्रत्येक पुस्तकालय प्रत्येक प्रतिनिधि पैटर्न के लिए अपने स्वयं के प्रतिनिधि प्रकार की घोषणा करता है, तो वे पुस्तकालय तब तक हस्तक्षेप नहीं कर पाएंगे जब तक उपयोगकर्ता रूपांतरण करने के लिए प्रतिनिधियों को "ब्रिजिंग" नहीं करता।
// declare two delegate types, completely identical but different names:
public delegate void ExceptionHandler1(Exception x);
public delegate void ExceptionHandler2(Exception x);
// a method that is compatible with either of them:
public static void MyExceptionHandler(Exception x)
{
Console.WriteLine(x.Message);
}
static void Main(string[] args)
{
// can assign any method having the right pattern
ExceptionHandler1 x1 = MyExceptionHandler;
// and yet cannot assign a delegate with identical declaration!
ExceptionHandler2 x2 = x1; // error at compile time
}
सभी को फंक का उपयोग करने के लिए प्रोत्साहित करके, Microsoft उम्मीद कर रहा है कि यह असंगत प्रतिनिधि प्रकार की समस्या को कम करेगा। सभी के प्रतिनिधि एक साथ अच्छी तरह से खेलेंगे, क्योंकि उनका मिलान उनके पैरामीटर / रिटर्न प्रकारों के आधार पर किया जाएगा।
यह सभी समस्याओं को हल नहीं करता है, क्योंकि Func
(और Action
) out
या नहीं हो सकता हैref
पैरामीटर , लेकिन वे कम सामान्यतः उपयोग किए जाते हैं।
अपडेट: टिप्पणी में Svish कहते हैं:
फिर भी, Func से Predicate और वापस करने के लिए एक पैरामीटर प्रकार स्विच करना, कोई अंतर नहीं लगता है? कम से कम यह अभी भी बिना किसी समस्या के संकलन करता है।
हां, जब तक आपका कार्यक्रम केवल प्रतिनिधियों को विधियां प्रदान करता है, जैसा कि मेरे Main
कार्य की पहली पंक्ति में है। संकलक चुपचाप एक नया प्रतिनिधि कोड उत्पन्न करता है जो विधि को आगे बढ़ाता है। इसलिए मेरे Main
कार्य में, मैं समस्या के कारण के बिना x1
टाइप का ExceptionHandler2
हो सकता है।
हालाँकि, दूसरी पंक्ति में मैं पहले प्रतिनिधि को दूसरे प्रतिनिधि को सौंपने की कोशिश करता हूँ। यहां तक कि यह सोचा गया कि 2 प्रतिनिधि प्रकार में बिल्कुल समान पैरामीटर और रिटर्न प्रकार हैं, संकलक त्रुटि देता हैCS0029: Cannot implicitly convert type 'ExceptionHandler1' to 'ExceptionHandler2'
।
शायद इससे यह स्पष्ट हो जाएगा:
public static bool IsNegative(int x)
{
return x < 0;
}
static void Main(string[] args)
{
Predicate<int> p = IsNegative;
Func<int, bool> f = IsNegative;
p = f; // Not allowed
}
जब तक मैं सीधे ऐसा करता हूं, तब तक और चर IsNegative
को असाइन करने के लिए मेरी विधि पूरी तरह से अच्छी चीज है । लेकिन तब मैं उनमें से किसी एक चर को दूसरे को नहीं सौंप सकता।p
f