The previously accepted answer अच्छा है, लेकिन यह गलत है। शुक्र है, त्रुटि एक छोटा सा है। IEnumerable
के लिए जांच करना पर्याप्त नहीं है यदि आप वास्तव में इंटरफ़ेस के सामान्य संस्करण के बारे में जानना चाहते हैं; वहां बहुत सारी कक्षाएं हैं जो केवल नोंगनेरिक इंटरफ़ेस को लागू करती हैं। मैं एक मिनट में जवाब दूंगा। हालांकि, सबसे पहले मैं कहना है कि स्वीकार किए जाते हैं जवाब बहुत ज्यादा जटिल है, चाहते हैं के बाद से निम्नलिखित कोड दिया परिस्थितियों में एक ही प्राप्त होगा:
if (items[key] is IEnumerable)
यह करता है और भी अधिक है, क्योंकि यह अलग से प्रत्येक आइटम के लिए काम करता है (और उनके सामान्य उप-वर्ग पर नहीं, V
)।
अब, सही समाधान के लिए।
static bool IsGenericEnumerable(Type t) {
var genArgs = t.GetGenericArguments();
if (genArgs.Length == 1 &&
typeof(IEnumerable<>).MakeGenericType(genArgs).IsAssignableFrom(t))
return true;
else
return t.BaseType != null && IsGenericEnumerable(t.BaseType);
}
आप आसानी से इस कोड की सत्यता की जांच कर सकते हैं: यह थोड़ा और अधिक जटिल है क्योंकि हम सामान्य प्रकार IEnumerable`1
(अर्थात, एक प्रकार पैरामीटर के साथ प्रकार IEnumerable<>
है) लेने के लिए और सही सामान्य तर्क इंजेक्षन करने के लिए है है :
var xs = new List<string>();
var ys = new System.Collections.ArrayList();
Console.WriteLine(IsGenericEnumerable(xs.GetType()));
Console.WriteLine(IsGenericEnumerable(ys.GetType()));
पैदावार:
True
False
ज्यादा तथ्य यह है कि इस प्रतिबिंब का उपयोग करता है से चिंतित न हो। हालांकि यह सच है कि यह रनटाइम ओवरहेड जोड़ता है, इसलिए is
ऑपरेटर का उपयोग करता है।
बेशक उपर्युक्त कोड बहुत ही सीमित है और इसे अधिक सामान्य रूप से लागू विधि, IsAssignableToGenericType
में विस्तारित किया जा सकता है। निम्नलिखित कार्यान्वयन थोड़ा गलत है और मैं इसे यहाँ ऐतिहासिक प्रयोजनों के लिए ही के लिए छोड़ देंगे। इसका उपयोग न करें।इसके बजाय, James has provided an excellent, correct implementation in his answer.
public static bool IsAssignableToGenericType(Type givenType, Type genericType) {
var interfaceTypes = givenType.GetInterfaces();
foreach (var it in interfaceTypes)
if (it.IsGenericType)
if (it.GetGenericTypeDefinition() == genericType) return true;
Type baseType = givenType.BaseType;
if (baseType == null) return false;
return baseType.IsGenericType &&
baseType.GetGenericTypeDefinition() == genericType ||
IsAssignableToGenericType(baseType, genericType);
}
यह विफल रहता है जब genericType
givenType
रूप में ही है; एक ही कारण के लिए, यह अर्थात
IsAssignableToGenericType(typeof(List<int>), typeof(List<>)) == false
IsAssignableToGenericType(typeof(int?), typeof(Nullable<>)) == false
नल प्रकार के लिए विफल रहता है, मैं एक gist with a comprehensive suite of test cases बना लिया है।
यह वही है जो मैं ढूंढ रहा था। धन्यवाद! यह अभी भी प्रतिबिंब का उपयोग करता है, लेकिन मैं "टाइपऑफ (आईनेमरेबल <>)" वाक्यविन्यास की तलाश में था। धन्यवाद! –
क्या "है" के अलावा अन्य प्रकार के चेक करने का कोई और तरीका नहीं है? –
अंतिम पंक्ति को 'रिटर्न (बेसटाइप.इसेजनेरिक टाइप और बेसटाइप.गेटजेनरिक टाइप टाइपिनिशन() == जेनेरिक टाइप) पढ़ना चाहिए || IsAssignableToGenericType (बेस टाइप, जेनेरिक टाइप); 'आप रिकर्सन से बच नहीं सकते क्योंकि बेस क्लास सामान्य है। –