2015-07-27 28 views
11

कार्यों के निम्नलिखित जोड़ी सी # 6.0 में अशक्त सशर्त ऑपरेटर उपलब्ध प्रतिकृति बनाने का प्रयास:सी # इस प्रकार अनुमानित विधि कॉल अस्पष्ट क्यों है?

public static TResult Bind<T, TResult>(this T obj, Func<T, TResult> func) 
    where T : class 
{ 
    return obj == null ? default(TResult) : func(obj); 
} 

public static TResult Bind<T, TResult>(this Nullable<T> obj, Func<T, TResult> func) 
    where T : struct 
{ 
    return obj.HasValue ? func(obj.Value) : default(TResult); 
} 

पहले समारोह वर्गों के लिए विवश है और एक String s के लिए मेरे जैसे कुछ लिखने के लिए अनुमति देता है:

var x = s.Bind(a => a.Substring(1)); 

दूसरा कार्य वह जगह है जहां मैं परेशानी में भाग रहा हूं। उदाहरण के लिए, दिए गए एक int? number मैं लिखने के लिए करना चाहते हैं:

The call is ambiguous between the following methods or properties: 'BindingExtensions.Bind<T, TResult>(T, Func<T, TResult>)' and 'BindingExtensions.Bind<T, TResult>(T?, Func<T, TResult>)'

मेरा अनुमान है कि इस बीच परस्पर क्रिया के साथ क्या करना है कि कुछ:

var y = number.Bind(a => a + 1); 

बहरहाल, यह मुझे निम्न त्रुटि देता है अज्ञात फ़ंक्शन और विधि अधिभार रिज़ॉल्यूशन का अनुमान टाइप करें। अगर मैं int के प्रकार को निर्दिष्ट करता हूं तो यह ठीक से संकलित करता है।

var y = number.Bind((int a) => a + 1); 

हालांकि, यह वांछनीय से स्पष्ट रूप से कम है। क्या कोई मुझे बता सकता है कि क्यों संकलक सोचता है कि उपरोक्त कॉल बांधने के लिए संदिग्ध है और/या इसे ठीक करने का तरीका प्रदान करता है? मुझे पता है कि मैं बस दो कार्यों को अलग-अलग नाम दे सकता हूं, लेकिन वह मजेदार क्या है?

+0

आप पहली बार एक पर बाधा को दूर कर सकता है और आप दूसरे की जरूरत नहीं होगी। बेशक फिर 'null' मान के लिए' number.ind (a => a + 1) 'का परिणाम 0 के बजाय 'null' होगा। लेकिन परिणाम यह है कि मैं वैसे भी उम्मीद करूंगा। – juharr

+0

@juharr हालांकि इस उद्देश्य को हर तरह से पराजित करेगा। मैं अज्ञात फ़ंक्शन को इनपुट करने की अपेक्षा करता हूं जो कभी भी शून्य नहीं हो सकता है, यही कारण है कि दूसरा फ़ंक्शन एक Nullable पर संचालित होता है लेकिन केवल अज्ञात फ़ंक्शन में टी को पास करता है। –

+1

आपका फ़ंक्शन 'शून्य' नहीं पारित किया जाएगा क्योंकि 'obj == null'' Nullable 'के लिए गलत है' गलत 'के साथ। बेशक इसका मतलब है कि आपके फ़ंक्शन को 'int' के बजाय 'Nullable ' की अपेक्षा करनी है, लेकिन वही है जो मैं वैसे भी उम्मीद करूंगा। – juharr

उत्तर

2

अधिभारित कार्यों को प्रकार की बाधाओं से असंबद्ध नहीं किया जा सकता है (देखें "Generic constraints, where T : struct and where T : class")। कोई भी शून्य प्रकार एन N : T और N : Nullable<T> को संतुष्ट करता है, जो क्रमशः पूर्व और बाद में Bind परिभाषाओं की आवश्यकता होती है। मुझे लगता है कि numberNullable<int> या इसी प्रकार का है।

var x = s.Bind(a => a.Substring(1)); 

क्योंकि s, प्रकार string की और सभी T नहीं string : Nullable<T> के लिए है, इसलिए केवल पहले अधिभार स्वीकार्य है यह स्पष्ट है।

var y = number.Bind(a => a + 1); 

यह अस्पष्ट है क्योंकि a => a + 1 के प्रकार या तो Func<int?,int?> या Func<int,int> के रूप में अनुमान लगाया जा सकता है। यदि Func<int?,int?> के रूप में अनुमानित पहला अधिभार लागू होता है, और यदि Func<int,int> के रूप में अनुमानित दूसरा ओवरलोड लागू होता है। यदि number, प्रकार Nullable<int> की है, उदाहरण के लिए

var y = number.Bind((int a) => a + 1); 

यह स्पष्ट है। सभी TT : Nullable<int> और T : int के लिए पहले अधिभार के लिए, इसलिए यह लागू नहीं होता है। दूसरे अधिभार के लिए आपको केवल T : int की आवश्यकता है जो आसानी से T = int से संतुष्ट है।

+3

'Nullable ' स्वयं ही है एक संरचना नहीं है? [लिंक] (https://msdn.microsoft.com/en-us/library/b3h38hb0 (v = vs.110) .aspx) तो वर्ग की बाधा को कैसे पूरा किया जा सकता है? –

+0

@Micah इस गलती को इंगित करने के लिए धन्यवाद। मैंने समस्या की अपनी व्याख्या में संशोधन किया है। – erisco

0

इस प्रयास करें:

public static TResult Bind<T, TResult>(this T? obj, Func<T?, TResult> func) 
    where T : struct 
    { 
     return obj.HasValue ? func(obj.Value) : default(TResult); 
    } 
+2

यह समस्या को ठीक करता है, आपको यह समझाने की आवश्यकता है कि मुझे क्यों लगता है कि – Fredou

+0

यह वास्तव में काम करता है, लेकिन मैं वास्तव में स्पष्टीकरण देखना चाहता हूं। सोचा नहीं कि मुझे नहीं लगता कि ओपी समारोह में 'शून्य' को पार करने से खुश होगा। – juharr

+1

ठीक है, यह काम करेगा, लेकिन सवाल पर मैंने दी गई टिप्पणियां देखें। Func के लिए तर्क 'टी' नहीं होना चाहिए, क्योंकि यह कभी भी शून्य नहीं होगा। –

संबंधित मुद्दे