2010-05-27 30 views
6

निर्धारित करने के लिए मेरे पास कई टेम्पलेटेड ऑब्जेक्ट्स हैं जो सभी एक ही इंटरफ़ेस को लागू करते हैं:सी # जेनेरिक प्रकार

आईई।

MyObject<datatype1> obj1; 
MyObject<datatype2> obj2; 
MyObject<datatype3> obj3; 

मैं एक सूची में इन वस्तुओं संग्रहीत करना चाहते हैं ... मुझे लगता है कि मुझे लगता है कि इस तरह से करना होगा:

private List<MyObject<object>> _myList; 

मैं तो, एक समारोह है कि 1 पैरामीटर लेता है बनाने के लिए एक डेटाप्रकार जा रहा है चाहता हूँ , यह देखने के लिए कि क्या उस डेटाटाइप का उपयोग करने वाला कोई ऑब्जेक्ट मेरी सूची में मौजूद है .... sorta इस बारे में जानने के लिए अनजान है। छद्म कोड में यह होगा:

public bool Exist(DataType T) 
{ 
    return (does _myList contain a MyObject<T>?); 
} 

कुछ स्पष्टीकरण ....

मेरे इंटरफेस IMyObject<T> है, मेरे वस्तुओं MyObject<T> हैं। मेरे पास एक नई कक्षा MyObjectManager है जिसमें मुझे MyObject<T> की एक सूची रखने की आवश्यकता है। मुझे यह जांचने के लिए एक फ़ंक्शन चाहिए कि MyObject<T> उस सूची में मौजूद है या नहीं। प्रकार T डेटाटाइप हैं जो टी 4 का उपयोग करके स्वत: जेनरेट किए गए थे .... मेरे एंटिटी डेटा मॉडल से पीओसीओ कक्षाएं। यह जरूरी है कि आप जानते हैं कि संकलन समय पर T

public bool Exists<T>() where T : class { 
    return _myList.OfType<MyObject<T>>().Any(); 
} 

नोट:

+0

क्या अगर यह एक 'MyObject शामिल 'और' यू 'विरासत 'टी'? – SLaks

+0

वैसे मेरा यू टी 4 और ईएफ पॉको कक्षाओं का उपयोग कर ऑटो जेनरेट किया गया है। –

+0

कक्षाएं एक दूसरे के उत्तराधिकारी हैं? – SLaks

उत्तर

6

आप एक सामान्य समारोह बना सकते हैं।

public bool Exists(Type t) { 
    var objectOfT = typeof(MyObject<>).MakeGenericType(t); 

    return _myList.Any(o => o.GetType() == objectOfT); 
} 

हालांकि, ध्यान रखें कि एक List<MyObject<object>> एक MyObject<SomeType> धारण नहीं कर सकता:

यदि आप केवल इतना है रनटाइम पर एक System.Type वस्तु है, तो आप प्रतिबिंब का उपयोग करना होगा।
आपको सूची को List<object> पर बदलने की आवश्यकता है, या MyObject को गैर-सामान्य प्रकार को लागू या प्राप्त करने और सूची को उस प्रकार में शामिल करने की आवश्यकता है।

+0

मेरी कक्षा जो सूची को संग्रहित करती है, उसके पास सामान्य प्रकार नहीं होगा, हालांकि टी इन मायऑब्जेक्ट संकलन समय पर ज्ञात है और इन वस्तुओं के लिए नामस्थान इस कक्षा में संदर्भित है। जब मैं आपका पहला उदाहरण आज़माता हूं तो यह कहता है कि टाइप टी को पैरामीटर के रूप में उपयोग करने के लिए संदर्भ प्रकार होना चाहिए। मैं चाहता हूं कि टी एक सामान्य प्रकार हो, इसलिए मैं किसी भी डेटाटाइप में पास कर सकता हूं, चाहे वह int, string, आदि –

+0

आपको 'MyObject' में बाधा से मेल खाने के लिए' जहां टी: क्लास 'contstraint जोड़ने की आवश्यकता है। – SLaks

+0

समझ गया ... सार्वजनिक बूल जोड़ना पड़ा () जहां टी: कक्षा .... धन्यवाद! –

0

चूंकि वे सभी एक ही इंटरफ़ेस को लागू करते हैं, उन्हें ऑब्जेक्ट करने और गेटटाइप (जो महंगा हो सकता है) को कॉल करने के बजाय, क्लास नाम (या कुछ) नामक आपके इंटरफ़ेस में कोई संपत्ति क्यों नहीं जोड़ते? फिर आप उस संपत्ति को पकड़ने के लिए linq का उपयोग कर सकते हैं। और भूल नहीं है using System.Linq

using System.Linq; 

public bool Exist(List<IMyInterface> objects, IMyInterface typeToCheck) 
{ 
    return objects.Any(t => t.ObjectName == typeToCheck.ObjectName); 
} 
+0

मेरा इंटरफ़ेस IMyInterface है –

1

कैसे एक विस्तार विधि के बारे में?

public static bool HasAny(this IEnumerable source, Type type) { 
    foreach (object item in source) 
     if (item != null && item.GetType().Equals(type)) 
      return true; 

    return false; 
} 

उपयोग:

bool hasDataType1 = myList.HasAny(typeof(MyObject<datatype1>)); 

ध्यान दें कि यदि आप नहीं करते हैं करने के लिए typeof(...) बाहर टाइप करना चाहते हैं - यानी, अगर आप मूल रूप से प्रकार की वस्तुओं के बारे में अपनी Exist विधि को केवल देखभाल चाहते हैं MyObject<T>, मैं SLaks के जवाब की तरह कुछ के साथ जाना चाहते हैं:

public static bool Exist<T>(this IEnumerable source) { 
    return source.OfType<MyObject<T>>().Any(); 
} 

इसके अलावा, SLaks सही है कि आप r ईली में List<MyObject<object>> नहीं हो सकता है जो MyObject<object> या कुछ व्युत्पन्न वर्ग (और MyObject<datatype1> इत्यादि) की वस्तुओं के अलावा कुछ भी भरा हुआ है।MyObject<object> से प्राप्त करें - जेनेरिक इस तरह से काम नहीं करते हैं)।

एक और तरीका है मैं पूरी "आप प्रतिबिंब का उपयोग किए बिना एक System.Type वस्तु का उपयोग कर एक सामान्य वर्ग के प्रकार नहीं मिल सकता है" समस्या के समाधान के लिए इस होगा सुझाव दे सकता है: अपने MyObject<T> बनाओ एक गैर सामान्य इंटरफ़ेस को लागू है, जैसे इस:

public interface IMyObject { 
    Type DataType { get; } 
} 

public class MyObject<T> : IMyObject<T>, IMyObject { 
    public Type DataType { 
     get { return typeof(T); } 
    } 
} 

फिर अपने सूची एक List<IMyObject> (गैर जेनेरिक इंटरफेस) हो सकता है और अपने Exist विधि ऐसा दिखाई दे सकता:

public static bool Exist<T>(this IEnumerable source, Type type) { 
    return source.OfType<IMyObject>().Any(x => x.DataType.Equals(type)); 
} 
संबंधित मुद्दे