2011-03-22 16 views
17

मैं हाल ही में लैम्ब्डा अभिव्यक्तियों में डाइविंग व्यस्त रहा हूं, और कुछ विशिष्ट कार्यक्षमता है जिसका मुझे सीखने का अर्थ रहा है लेकिन केवल सिर या पूंछ नहीं लग रहा था।सी # लैम्ब्डा अभिव्यक्ति फ़ंक्शन तर्क के रूप में

मान लीजिए कि मैं अपने कोड में निम्न तर्क होते हैं:

List<A> foo; // assuming this is populated 
string[] bar = foo.Select<A,string>(x => x.StringProperty).ToArray<string>(); 

अब, मैं शायद सार हैंडलर विधि में पूरे आपरेशन ताकि मैं बजाय यह कर सकते हैं कि करना चाहते हैं:

string[] bar = MakeArray<A,string>(foo, x => x.StringProperty); 
int[] foobar = MakeArray<A,int>(foo, x => x.IntegerProperty); 

मैं उस विधि के शरीर को लिखने के साथ कैसे जाउंगा? मैं की तरह कुछ के रूप में हस्ताक्षर घोषित पूर्वानुमान:

U[] MakeArray<T,U>(/* some lambda magic? */) where T : IEntity {} 

लेकिन मुझे लगता है कि मैं विधि तर्क के रूप में एक लैम्ब्डा अभिव्यक्ति की उम्मीद कर रहा हूँ निर्दिष्ट करने के लिए कैसे पता नहीं है, और कैसे है कि वास्तव में विधि के शरीर में तब्दील हो।

क्या कोई मुझे दिखा सकता है कि ऊपर MakeArray() फ़ंक्शन कैसे बनाएं? मुझे पूरा यकीन है कि एक बार जब मैं देखता हूं कि यह कैसे किया जाता है, तो मैं इसे वहां से उठा सकता हूं।

संपादित

के रूप में टिप्पणी में कहा, MakeArray()IEnumerable<> के लिए एक संदर्भ की जरूरत है। इसे प्रतिबिंबित करने के लिए अद्यतन किया गया।

+5

FWIW की तरह उपयोग जेनरिक के अंतर्निहित प्रकृति कर सकते हैं: LINQ कहाँ एक उदाहरण के लिए समारोह के हस्ताक्षर की जाँच करें प्रत्येक कथन के साथ प्रकार को स्पष्ट रूप से बताए बिना अपने कोड में एक पठनीय मूल्य जोड़ सकते हैं, हालांकि यह व्यक्तिपरक हो सकता है। निम्नलिखित कथन आपके पहले चयन के बराबर है .. 'स्ट्रिंग [] बार = foo.Select (x => x.StringProperty) .oorray(); ' –

+0

यदि आप अपने कोड पर अपने आप को सरणी का उपयोग करते हैं, तो आप चाह सकते हैं उन्हें 'IENumerable ' या 'IList ' में पुन: सक्रिय करने पर विचार करें। तब इनमें से कोई भी आवश्यक नहीं होगा। साथ ही, 'MakeArray' को foo के संदर्भ की आवश्यकता नहीं है? –

+0

@ क्विंटिन ~ हाँ, मैं बस जेनिक्स की तरह स्पष्ट रूप से बताता हूं (जब लागू हो) बस इतना स्पष्ट है कि मैं क्या खींच रहा हूं। हालांकि आप सही हैं। –

उत्तर

16
public static U[] MakeArray<T, U>(this IEnumerable<T> @enum, Func<T, U> rule) 
{ 
    return @enum.Select(rule).ToArray(); 
} 
+0

+1 धन्यवाद! मैं यह जवाब देने के लिए जा रहा हूं कि विधि में आने वाले Func <> पैरामीटर का उपयोग कैसे किया जाता है। असली सहायक –

2

आप Action<> और Func<> देख रहे हैं।

13

जब तर्कों के रूप lambdas गुजर निम्नलिखित

U[] MakeArray<T,U>(Func<T, U> projection) where T : IEntity { 
    ... 
} 

प्रयास करें आप आमतौर पर मिलान पैरामीटर एक प्रतिनिधि होना चाहता हूँ। ज्यादातर मामलों में आपको उचित Action<> या Func<> मान का उपयोग करना चाहिए। शून्य लौटने के लिए पूर्व lambdas और बाद वाले मूल्यों के लिए जो मूल्य वापस।

+0

+1 धन्यवाद!मैं विशेष रूप से स्पष्टीकरण की भी सराहना करता हूं। –

2

आप फनक और एक्शन क्लासेस का उपयोग कर सकते हैं। http://msdn.microsoft.com/en-us/library/bb534803.aspx

+0

लिंक के लिए धन्यवाद! मैंने हमेशा सोचा कि उन्होंने उस जादू को कैसे लागू किया। – Colin

1

आप विस्तार

public static class MakeArrayExtension 
{ 
    public static U[] MakeArray<T, U>(this IEnumerable<T> collection, Func<T,U> func) 
    { 
     return collection.Select(func).ToArray(); 
    } 
} 

बनाने और फिर इस

List<A> foo; // assuming this is populated 
string[] bar = foo.MakeArray<A,string>(x => x.StringProperty); 
संबंधित मुद्दे