2010-08-10 12 views
6

LinQ विधि कास्ट जो टाइप करने के लिए टी सूची में प्रत्येक प्रविष्टि डाले हैं। कहते हैं कि हम एक सूची है जो ऐसा दिखाई देता है की सुविधा देता है:Linq System.Type साथ <T> कास्ट

List<Object> obj = new List<Object>(); 
obj.Add("A"); 
obj.Add("B"); 

एक काम कर डाली हो सकता है

var list = obj.Cast<string>(); 

मैं

Type t = typeof(String); 
Object list = obj.Cast(t); 

एक समाधान का उपयोग करने के होगा काम करने के लिए चाहते हैं क्या प्रतिबिंब और सामान्य रूप से एक सूची बनाएं और इसे पॉप्युलेट करें लेकिन मैं सोच रहा था कि क्या कोई बेहतर समाधान मौजूद है? सुना है कि .NET 4.0 को कुछ सह/अनुबंध-भिन्नता का समर्थन करना चाहिए जो इसे करने का एक तरीका हो सकता है।


अतिरिक्त सूचना और प्रतिबिंब soulution

त्रुटि मैं निम्नलिखित The model item passed into the dictionary is of type System.Collections.Generic.List1[IStatisticEntry], but this dictionary requires a model item of type System.Collections.Generic.List1[CrashStatistic+CrashEntry] है। ध्यान दें कि क्रैशएन्ट्री IStaticEntry लागू करता है लेकिन इसे कास्ट नहीं किया जा सकता क्योंकि यह सूची का एक सामान्य प्रकार है।

मैं के माध्यम से निम्नलिखित समाधान का निर्माण मैं करूंगा Stille प्रतिबिंब के बिना कुछ की तरह:

public static object Cast(this IEnumerable list, Type type) 
    { 
     var newList = Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); 

     foreach (var item in list) 
      newList.GetType().GetMethod("Add").Invoke(newList, new object[] { item }); 

     return newList; 
    } 
+0

http://geekswithblogs.net/abhijeetp/archive/2010/01/10/covariance-and-contravariance-in-c-4.0.aspx –

उत्तर

2

यह स्थिर रूप से ऐसा करना संभव नहीं है, आप इसे एक ही वस्तु के साथ कर सकते हैं।

Type t = typeof(string); 
var x = (t)obj; // invalid 

हालांकि, यह तत्व गतिशील के इलाज के लिए संभव है ताकि अंतर्निहित प्रकार के लिए एक डाली नहीं आवश्यक है:

static void Main(string[] args) 
{ 
    List<Object> obj = new List<Object>(); 
    obj.Add("A"); 
    obj.Add("B"); 

    var list = obj.Cast<dynamic>(); 
    foreach (var item in list) 
    { 
     Console.WriteLine(item[0]); 
    } 

    Console.ReadKey(); 
} 
+0

प्रतिक्रिया के लिए धन्यवाद लेकिन मुझे नहीं लगता कि यह समस्या का समाधान है। मेरे पास एक दृश्य है जो एक निश्चित प्रकार के मॉडल की अपेक्षा करता है और मुझे टाइप पैरामीटर के रूप में मिला है। –

+0

से ऊपर समस्या विवरण में त्रुटि के बारे में कुछ जानकारी जोड़ा गया है यदि आपके पास केवल रन-टाइम प्रकार है (उदा।, 'टाइप' का एक उदाहरण) और संकलन-समय प्रकार (उदा।, एक ' 'सामान्य पैरामीटर), तो आपको प्रतिबिंब या' गतिशील 'का उपयोग करना होगा (और आपको' गतिशील' का उपयोग करने के लिए दृश्य को बदलना होगा)। तो, आपके विकल्प हैं: 1) प्रतिबिंब का उपयोग करें; 2) 'गतिशील' का उपयोग करें, दृश्य को बदलना; 3) प्रकार को 'टाइप' उदाहरण के बजाय सामान्य पैरामीटर '' के रूप में पास करें। –

+0

पर्याप्त उचित, विषय पर स्पष्टता के लिए धन्यवाद। मेरे टाइपो की मात्रा के साथ मेरा मानना ​​है कि सबसे अच्छा तरीका प्रतिबिंब समाधान है यह सुनिश्चित करने के लिए कि विचार अभी भी दृढ़ता से टाइप किए गए मॉडल के साथ काम करते हैं :) –

0

आप प्रकार है कि आप केवल क्रम में पता चल जाएगा पर कुछ कास्ट करने के लिए जरूरत नहीं है। ऑब्जेक्ट का प्रकार बदलेगा क्योंकि आप कास्ट करेंगे, अगर यह स्ट्रिंग था तो यह बाद में एक स्ट्रिंग होगा और इससे कोई फर्क नहीं पड़ता कि आप इसे स्ट्रिंग या ऑब्जेक्ट वैरिएबल को असाइन करेंगे।

आपको प्रतिबिंब विधियों पर परिचालन करते समय वास्तविक ऑब्जेक्ट प्रकार पर कास्टिंग करने की परवाह करने की आवश्यकता नहीं है। यह ऑब्जेक्ट वैरिएबल के रूप में रह सकता है क्योंकि प्रतिबिंब का उपयोग करते समय आप बिना किसी कलाकार के अपने सभी वास्तविक प्रकार के सदस्यों तक पहुंच सकते हैं।

+0

मैंने ऊपर त्रुटि विवरण जोड़ा, लगता है कि यह एक और स्पष्ट विचार देता है मेरा मतलब। –

4

मैं काफी समझ में नहीं आता क्यों आप क्या करना चाहते चाहते हैं इस लेकिन आप प्रतिबिंब के माध्यम से Enumerable.Cast<T> आह्वान सकता:

List<object> objectList = new List<object> { "Foo", "Bar" }; 
object stringSequence = typeof(Enumerable) 
    .GetMethod("Cast", BindingFlags.Public | BindingFlags.Static) 
    .MakeGenericMethod(typeof(string)) 
    .Invoke(null, new[] { objectList }); 

जो मामले में stringSequence के क्रम प्रकार IEnumerable<string> लागू करेगा।

+0

+1 आप, महोदय, एक सज्जन और विद्वान दोनों हैं। –

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