फंक <T> आउट पैरामीटर के साथ


167

क्या मैं फंक के रूप में आउट पैरामीटर के साथ एक विधि पारित कर सकता हूं?

public IList<Foo> FindForBar(string bar, out int count) { }

// somewhere else
public IList<T> Find(Func<string, int, List<T>> listFunction) { }

फंक को एक प्रकार की आवश्यकता होती है, इसलिए वहां कोई संकलन नहीं होगा, और कॉलिंग सूची को एक इंट की आवश्यकता होती है और एक आउट की अनुमति नहीं देगा।

क्या इसे करने का कोई तरीका है?

जवाबों:


228

refऔर outप्रकार पैरामीटर परिभाषा का हिस्सा नहीं हैं, ताकि आप Funcपास refऔर outतर्क के लिए अंतर्निहित प्रतिनिधि का उपयोग न कर सकें । यदि आप चाहें तो बेशक, आप अपने स्वयं के प्रतिनिधि की घोषणा कर सकते हैं:

delegate V MyDelegate<T,U,V>(T input, out U output);

7
C # 4 (2010) और बाद में (जब आपने अपना उत्तर लिखा था तब जारी नहीं किया गया था) यह Tकंट्राविरेंट, और Vसहसंयोजक के रूप में चिह्नित करना संभव है । हालांकि, एक पैरामीटर के बाद से ( outputप्रकार के) Uपारित कर दिया है संदर्भ द्वारा , Uसह या contravariant नहीं चिह्नित किया जा सकता है और "अपरिवर्तनीय" रहना चाहिए। इसलिए विचार करें public delegate V MyDelegate<in T, U, out V>(T input, out U output);कि क्या आप C # 4 या बाद का उपयोग करते हैं।
जेपी स्टिग नीलसन


24

परिणामों को एन्कैप करने के लिए एक वर्ग क्यों नहीं बनाया गया?

public class Result
{
     public IList<Foo> List { get; set; }
     public Int32 Count { get; set; }
}

13

Funcप्रतिनिधियों का परिवार (या Actionउस मामले के लिए) कुछ और नहीं बल्कि साधारण प्रतिनिधि प्रकारों को घोषित किया जाता है

//.NET 4 and above
public delegate TResult Func<out TResult>()
public delegate TResult Func<in T, out TResult>(T obj)

//.NET 3.5
public delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2)
public delegate TResult Func<T1, T2, T3, TResult>(T1 obj1, T2 obj2, T3 obj3)

आदि के रूप में इस तरह के बाहर / रेफरी पैरामीटर हो सकता है, इसलिए अपने मामले में अपने आप ही कस्टम कार्यान्वयन के एक मामले के रूप में अन्य जवाब बताया है। जैसे कि Microsoft ने इसे डिफ़ॉल्ट रूप से क्यों नहीं पैक किया, सोचें कि इसके लिए कितने संयोजन की आवश्यकता होगी।

delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2)
delegate TResult Func<T1, T2, TResult>(out T1 obj1, T2 obj2)
delegate TResult Func<T1, T2, TResult>(T1 obj1, out T2 obj2)
delegate TResult Func<T1, T2, TResult>(out T1 obj1, out T2 obj2)

सिर्फ दो मापदंडों के लिए। हमने छुआ भी नहीं है ref। यह वास्तव में डेवलपर्स के लिए बोझिल और भ्रमित करने वाला होगा।


2
ध्यान दें कि C # फ़ंक्शन ओवरलोडिंग के बीच अंतर नहीं कर सकता है delegate TResult Func<T1, T2, TResult>(T1 obj, T2 obj)और delegate TResult Func<T1, T2, TResult>(out T1 obj, T2 obj)। इसलिए ओवरलोड्स की संख्या के अलावा प्रतीक नाम एक अन्य कारण है जिसके कारण Microsoft इन ओवरलोडों को जोड़ नहीं सका Func
कैस्पर वैन डेन बर्ग

क्या कोई मुझे ऊपर के प्रतिनिधियों पर एमएसडीएन लेख का उल्लेख कर सकता है?
सु लेलीवेन

@SuLlewellyn मैं मूल msdn लेख नहीं ढूंढ सका, लेकिन आप कोशिश कर सकते हैं: docs.microsoft.com/en-us/dotnet/api/… , docs.microsoft.com/en-us/dotnet/api/…
nawfal

0

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.