2011-04-28 15 views
14

मैं खुद का एक उदाहरण वापस करने के लिए एक विधि लिखने की कोशिश कर रहा हूं। छद्म कोडमैं सी # में एक प्रतिनिधि समारोह या लैम्ब्डा अभिव्यक्ति कैसे वापस कर सकता हूं?

Func<T,Func<T>> MyFunc<T>(T input) 
{ 
    //do some work with input 
    return MyFunc; 
} 

काफी आसान लगता है। लेकिन मुझे रिटर्न प्रकार को परिभाषित करने में समस्या आ रही है। वापसी प्रकार एक प्रतिनिधि

which takes T as parameter, then returns a function 
which takes T as parameter, then returns a function 
which takes T as parameter, then returns a function 

    ...recursive definition 

मुझे यकीन है कि कुछ सूक्ष्म बात यह है कि मैं नोटिस नहीं किया था हूँ होना चाहिए। क्या कोई इसे मेरे लिए इंगित कर सकता है? धन्यवाद।

+0

मैं सोच रहा हूँ कि आप इस –

+0

करने के लिए मैं एक उपयोगिता विधि है, जो एक के अंदर स्थिर है लिख रहा था कोशिश कर रहे हैं स्थैतिक वर्ग मैं भी "धाराप्रवाह" कार्यक्षमता MyFunc (ए) होना चाहता हूँ। MyFunc (बी) ... लेकिन जब से मैं एक स्थिर वर्ग के अंदर हूँ। कक्षा के एक उदाहरण को वापस करना संभव नहीं है। –

उत्तर

15

आप इस तरह यह कर सकते हैं:

delegate F<T> F<T>(T obj); 

F<T> MyFunc<T>(T obj) 
{ 
    return MyFunc; 
} 

लेकिन यह काफी बेकार है।

void Main() 
{ 
    MyFunc(1)(2)(3)(4); 
} 

delegate F<T> F<T>(T obj); 

F<T> MyFunc<T>(T obj) 
{ 
    Console.WriteLine(obj); 
    return MyFunc; 
} 
+0

डुनो क्यों मैंने इसके बारे में नहीं सोचा था ... +1। – Justin

+1

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

+0

यह एक आकर्षण की तरह काम किया। धन्यवाद दोस्त। –

2

यह एक पुनरावर्तक की तरह बहुत लगता है।

कहाँ T अपने इनपुट प्रकार और P है अपने परिणाम प्रकार है: क्या आप की तरह कुछ होने के लिए अपने कोड refactor कर सकते हैं। समान नहीं है, लेकिन यह काम पूरा करना चाहिए।

संपादित करें: यदि आप एक धाराप्रवाह इंटरफ़ेस चाहते हैं, तो पैटर्न पत्थर में काफी सेट है: आप एक गैर स्थैतिक वर्ग बनाते हैं और इसे प्रत्येक फ़ंक्शन (जो स्थिर नहीं है) से वापस लौटाते हैं। एक स्थिर वर्ग के गैर स्थैतिक संस्करण को सिंगलटन कहा जाता है और आप इसे इस पैटर्न के लिए उपयोग कर सकते हैं।

+0

मैं वास्तव में इस उपयोगिता विधि का उपयोग करने की कोशिश कर रहा हूं, LINQ2Object फ़ंक्शन जैसे कहां, चयन, इत्यादि को लागू करने के लिए कुछ सामान्य कार्य करता हूं। आप कोड सभी अच्छे हैं लेकिन यह "असली" काम का हिस्सा है। मेरी उपयोगिता विधि इस भाग को चलाने से पहले त्रुटि जांच के लिए इरादा रखती है। –

1

मुझे यकीन नहीं है कि आप क्या हासिल करने की कोशिश कर रहे हैं, लेकिन एक अभिन्न अभ्यास के रूप में "क्या मैं एक विधि वापस कर सकता हूं जो खुद को लौटाता है?" निम्नलिखित काम करता है:

object MyFunc<T>(T input) 
{ 
    Func<T, object> returnValue = MyFunc; 
    return returnValue; 
} 

जैसा आप कहते हैं, आप विधि एक Func वापसी के रूप में इस है कि प्रतिनिधि की वापसी प्रकार का मतलब होगा नहीं हो सकता है कि रिटर्न एक Func कि एक Func आदि देता है एक Func करने की आवश्यकता होगी ...

इस अनंत भूकंप से बाहर निकलने का एकमात्र तरीका यह है कि यह object इसके बदले में है, जिसके लिए कॉलर सही प्रकार पर डाला जाता है।

संपादित करें: Porges जवाब बेहतर है ...

+0

जैसा कि मैंने porges के जवाब में लिखा था। मैं त्रुटि जांच कोड लिख रहा था जो बहुत दोहराता है। ऐसा करके, कोड बहुत terser है। –

+0

@WeiMa एक विकल्प शायद 'पैराम्स' का उपयोग करने के लिए किया गया हो - व्यक्तिगत रूप से मैं अपनी त्रुटि को स्पष्ट रूप से संभालना पसंद करता हूं। यहां तक ​​कि अगर यह अधिक verbose, यह आम तौर पर इसे पढ़ने के लिए स्पष्ट बनाता है। किसी भी मामले में यह एक दिलचस्प सवाल था। – Justin

+0

या यदि आप कास्ट करने के लिए सहेजने के लिए .NET4 का उपयोग कर रहे हैं तो गतिशील वापस आएं। – Michael

3

यह करने के लिए एक और तरीका है एक Combinator बनाना है: केवल एक चीज आप वास्तव में क्या कर सकते हैं कुछ इस तरह है, जो अजीब है। आसान peasy, लेकिन आप उस अनंत वापसी के कारण जेनेरिक के साथ ऐसा नहीं कर सकते हैं। आपको इसे सीधे घोषित करना होगा:

delegate D D(D d); 

यही है, डी एक प्रतिनिधि है जो डी लेता है और डी देता है।

static D MyCombinator(D d) 
{ 
    return MyCombinator; 
} 

सी # यहाँ में combinators इस पर कुछ और विचार:

http://blogs.msdn.com/b/ericlippert/archive/2006/06/23/standard-generic-delegate-types-part-two.aspx

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