2012-09-29 11 views
6

मैं इसकैसे जांचें कि एक सामान्य विधि का एक प्रकार टी है Inumerable <> और लूप?

void DoSomething<T>(T param) 
{ 
    if param is IEnumerable<?> 
    { 
     loop param and do stuff 
    } 
} 

मैं क्या प्रश्न चिह्न के स्थान पर क्या करने के लिए पता नहीं है की तरह कुछ करने के लिए करना चाहते हैं। और क्या यह बिल्कुल संभव है?

+0

यदि 'param' टाइप नहीं है' IEnumerable ', क्या आप कुछ करना चाहते हैं? यदि नहीं, तो 't' को' i'umerable 'टाइप करने के लिए क्यों नहीं प्रतिबंधित करें [http://msdn.microsoft.com/en-us/library/bb384067.aspx)? –

+0

संभव यहाँ जवाब: http://stackoverflow.com/questions/1846671/determine-if-collection-is-of-type-ienumerablet –

+0

ढेर अतिप्रवाह पोस्ट में उत्तर [यहां क्लिक करें] [1] [1]: http://stackoverflow.com/questions/906499/getting-type-t-from-ienumerablet –

उत्तर

7

क्या आप के लिए देख रहे हैं:

if (T is IEnumerable) { .. } 

लेकिन अगर आप टी हर समय IEnumerable होने की उम्मीद आप कर सकते हैं:

void DoSomething<T>(T param) where T : IEnumerable 
{ 
    foreach (var t in param) { ... } 
} 

या IEnumerable अंदर मूल्यों के प्रकार की जाँच :

public void DoSomething<T,U>(T val) where T : IEnumerable<U> 
{ 
    foreach (U a in val) 
    { 
    } 
} 

इसे स्वयं जांचने के लिए चिंता किए बिना, संकलक आपके लिए यह करेगा, जो एक स्थिर प्रकार प्रणाली और संकलक होने के अच्छा चीजों में से एक है :)

+0

मुझे लगता है कि वह वास्तव में एक सामान्य प्रकार के आईनेमरेबल को जांचने का प्रयास करता है, न केवल एक सामान्य आईनेमरेबल। प्रश्न के तहत टिप्पणी में लिंक उस परिदृश्य को संभालता है –

+0

अच्छा बिंदु। मैं उस परिदृश्य के साथ जवाब पूरा करता हूं, धन्यवाद। –

+0

अच्छे उत्तर के लिए धन्यवाद। समस्या यह है कि मैं उम्मीद नहीं करता कि टी हर समय IENumerable हो। असल में, मेरे पास पहले से ही एक विधि 'शून्य प्रोसेस लिस्ट (आईनेमेरेबल सूची) है और यदि तर्क एक आईनेमरेबल है तो इसे' DoSomething() 'में पुन: उपयोग करना चाहते हैं। – tranmq

0

कुछ तरीके हैं: आप प्रत्येक इंटरफ़ेस के खुले सामान्य प्रकार की जांच करने के लिए है

void DoSomething<T>(T param) 
{ 
    if (param is IEnumerable) 
    { 
     foreach (var item in (IEnumerable)param) 
     { 
      // Do something 
     } 
    } 
} 

void DoSomething<T>(T param) 
{ 
    if (param is IEnumerable<string>) 
    { 
     foreach (var item in (IEnumerable<string>)param) 
     { 
      // Do something 
     } 
    } 
} 

void DoSomething<T,TItem>(T param) 
{ 
    if (param is IEnumerable<TItem>) 
    { 
     foreach (var item in (IEnumerable<TItem>)param) 
     { 
      // Do something 
     } 
    } 
} 
+0

सर्वोत्तम अभ्यास '''' प्लस-डायरेक्ट-कास्ट के बजाय 'as' का उपयोग करना है, क्योंकि' as' महंगा रन-टाइम प्रकार केवल एक बार जांचता है, जबकि-प्लस-डायरेक्ट-कास्ट इसे दो बार करता है। – phoog

0

उस वर्ग उपकरण, जैसे इसलिए:

bool implements = typeof(T).GetInterfaces().Where(t => t.IsGenericType && 
    t.GetGenericTypeDefinition() == typeof(IEnumerable<>)).Any(); 

यह आप यह निर्धारित करने या नहीं, एक प्रकार वास्तव में किस प्रकार T है जानने के बिना IEnumerable<T> लागू करता है की अनुमति देगा। याद रखें कि प्रकार IEnumerable<T> कई बार कार्यान्वित कर सकता है।

यदि आप बस IEnumerable<T> के लिए पैरामीटर टाइप प्रकारों के अनुक्रम चाहते हैं, तो आप उपर्युक्त क्वेरी को बदल सकते हैं;

IEnumerable<Type> types = typeof(T).GetInterfaces(). 
    Where(t => t.IsGenericType && 
     t.GetGenericTypeDefinition() == typeof(IEnumerable<>)). 
    Select(t => t.GetGenericArguments()[0]); 
+0

एक प्रकार का कार्यान्वयन 'IENumerable ' कई बार वास्तव में एक डरावना प्रकार है। – phoog

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