2012-05-09 18 views
6

नीचे कोड को एक गुमनाम प्रकार रिटर्न मान्य है:निरुपित एक समारोह प्रतिनिधि है कि एक चर

IEnumerable<SomeThing> things = ...; 

// map type SomeThing to a new anonymous type, resulting in a strongly typed 
// sequence based on an anon type 

var newList = things.Select(item => 
    { 
     return new 
     { 
      ID = item.ID, 
      DateUpdatedOrCreated = ((DateTime)(item.DateUpdated ?? 
        item.DateCreated)).ToShortDateString(), 
      Total = item.Part1 + item.Part2 
     }; 
    }); 

newList अब IEnumerable<'a> के रूप में दृश्य स्टूडियो में प्रकट होता है और दृढ़ता से समारोह में बनाया गुमनाम प्रकार के साथ लिखा गया। यह कितना शांत है।

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

var func = (SomeThing item)=> { 
     return new { ... }; 
    }; 

मैं त्रुटि "लैम्ब्डा अभिव्यक्ति परोक्ष टाइप करने के लिए स्थानीय चर निर्दिष्ट नहीं कर सकते" मिलता है। यह एक अजीब संकलक सीमा लगता है; जब तक कि मैं कुछ याद नहीं कर रहा हूं, प्रकार दूसरे उदाहरण में गैर-संदिग्ध हैं क्योंकि वे पहले पहले हैं: दोनों प्रकार के पैरामीटर अच्छी तरह परिभाषित हैं।

क्या ऐसा करने का कोई तरीका है? चूंकि यह एक अज्ञात प्रकार है, बेशक, मेरे पास स्पष्ट रूप से असाइन करने के लिए किसी प्रकार का उपयोग करने का कोई तरीका नहीं है, इसलिए ऐसा लगता है कि अगर आउटपुट प्रकार के लिए कक्षा बनाने के साथ मैं फंस जाऊंगा।

अद्यतन

कुछ ही समय जॉन स्कीट के जवाब के साथ अपने प्रमुदित तरीके के बारे में जाने के बाद, मैं एक ऐसी ही दुविधा कक्षाएं instantiating पाया। यदि यह स्पष्ट नहीं है, तो अनुमानित अनाम प्रकारों का उपयोग करके दृढ़ टाइप किए गए वर्ग बनाने के लिए एक ही चाल का उपयोग किया जा सकता है।

class Processor<T,U> 
{ 
    public Processor(Func<T,U> func) { 

    } 
} 

// func is a delegate with anon return type created using method in answer below 

var instance = new Processor(func); // does not compile! Requires type arguments! 

सीधे नहीं बनाया जा सकता है, लेकिन नीचे चाल के रूप में ज्यादा एक ही तरीके से बनाया जा सकता है:

public static Processor<T,U> Create<T,U>(Func<T,U> func) { 
    return new Processor<T,U>(func); 
} 

var instance = Processor.Create(func); // all good 

उत्तर

8

आप प्रकार निष्कर्ष के माध्यम से यह कर सकते हैं:

var func = BuildFunc((SomeThing item) => { 
    return new { ... }; 
}); 

... 

static Func<TSource, TResult> BuildFunc<TSource, TResult>(
    Func<TSource, TResult> function) { 
    return function; 
} 

ध्यान दें कि BuildFunc वास्तव में कुछ भी नहीं करता है - यह Func<,> के लिए सामान्य प्रकार के तर्कों के लिए कंपाइलर टाइप प्रकार अनुमान लगाने के लिए आवश्यक विधि कॉल प्रदान करता है - यह जानकारी था आप Func<,> में रुचि रखते हैं, मूल रूप से - वह जानकारी है जिसे एक प्रकार की घोषणा के भाग के रूप में निर्दिष्ट नहीं किया जा सकता है, बिना तर्क तर्क निर्दिष्ट किए।

+0

यह काम करता है क्योंकि जेनिक्स के लिए टाइप अनुमान 'var' के प्रकार प्रकार से अधिक स्मार्ट है। (मुझे लगता है कि जोन समझाने में सक्षम हो सकता है कि क्यों मैं नहीं कर सकता।) – Servy

+0

अच्छा जवाब। अतिरिक्त जानकारी: यह काम करता है क्योंकि आपको चर के प्रकार को निर्दिष्ट करने की आवश्यकता नहीं है। कंपाइलर केवल चर के लिए प्रकार का अनुमान नहीं लगा सकता है क्योंकि इसमें से कई प्रतिनिधि प्रकार चुन सकते हैं। – usr

+0

@ सर्वी: यह वास्तव में स्मार्ट होने की बात नहीं है - यह निर्दिष्ट करने में सक्षम है कि आप 'Func' प्रतिनिधि चाहते हैं, लेकिन सामान्य रूप से निर्दिष्ट करना चाहते हैं। –

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