जवाबों:
यदि आप यह देखना चाहते हैं कि क्या यह सामान्य प्रकार का उदाहरण है:
return list.GetType().IsGenericType;
यदि आप यह देखना चाहते हैं कि क्या यह सामान्य है List<T>
:
return list.GetType().GetGenericTypeDefinition() == typeof(List<>);
जैसा कि जॉन बताते हैं, यह सटीक प्रकार की समानता की जांच करता है। रिटर्निंग का false
मतलब list is List<T>
रिटर्न नहीं है false
(यानी ऑब्जेक्ट को किसी List<T>
वैरिएबल को नहीं सौंपा जा सकता है )।
मेरा मानना है कि आप केवल यह जानना नहीं चाहते हैं कि क्या प्रकार सामान्य है, लेकिन यदि कोई वस्तु किसी विशेष जेनेरिक प्रकार का उदाहरण है, तो प्रकार के तर्क को जाने बिना।
यह बहुत सरल नहीं है, दुर्भाग्य से। यह बहुत बुरा नहीं है यदि सामान्य प्रकार एक वर्ग है (जैसा कि इस मामले में है) लेकिन यह इंटरफेस के लिए कठिन है। यहाँ एक वर्ग के लिए कोड है:
using System;
using System.Collections.Generic;
using System.Reflection;
class Test
{
static bool IsInstanceOfGenericType(Type genericType, object instance)
{
Type type = instance.GetType();
while (type != null)
{
if (type.IsGenericType &&
type.GetGenericTypeDefinition() == genericType)
{
return true;
}
type = type.BaseType;
}
return false;
}
static void Main(string[] args)
{
// True
Console.WriteLine(IsInstanceOfGenericType(typeof(List<>),
new List<string>()));
// False
Console.WriteLine(IsInstanceOfGenericType(typeof(List<>),
new string[0]));
// True
Console.WriteLine(IsInstanceOfGenericType(typeof(List<>),
new SubList()));
// True
Console.WriteLine(IsInstanceOfGenericType(typeof(List<>),
new SubList<int>()));
}
class SubList : List<string>
{
}
class SubList<T> : List<T>
{
}
}
संपादित करें: जैसा कि टिप्पणियों में कहा गया है, यह इंटरफेस के लिए काम कर सकता है:
foreach (var i in type.GetInterfaces())
{
if (i.IsGenericType && i.GetGenericTypeDefinition() == genericType)
{
return true;
}
}
मुझे इस बात पर संदेह है कि इसके आसपास कुछ अजीबोगरीब मामले हो सकते हैं, लेकिन मुझे अभी इसके लिए कोई असफलता नहीं मिली है।
List<T>
किसी अन्य रूप में मारा या नहीं। यदि आप इंटरफेस शामिल करते हैं, तो यह वास्तव में मुश्किल है।
IsInstanceOfGenericType
कॉल के साथ लूप को बदल नहीं सकते हैं ? IsAssignableFrom
==
आप डायनेमिक एल्थॉग का उपयोग करके छोटे कोड का उपयोग कर सकते हैं यह शुद्ध प्रतिबिंब की तुलना में धीमा हो सकता है:
public static class Extension
{
public static bool IsGenericList(this object o)
{
return IsGeneric((dynamic)o);
}
public static bool IsGeneric<T>(List<T> o)
{
return true;
}
public static bool IsGeneric( object o)
{
return false;
}
}
var l = new List<int>();
l.IsGenericList().Should().BeTrue();
var o = new object();
o.IsGenericList().Should().BeFalse();
ये मेरे दो पसंदीदा एक्सटेंशन तरीके हैं जो जेनेरिक प्रकार की जाँच के सबसे किनारे मामलों को कवर करते हैं:
के साथ काम करता है:
एक अधिभार है जो विशिष्ट जेनेरिक प्रकार को 'आउट' कर देगा यदि यह सच हो जाता है (नमूने के लिए इकाई परीक्षण देखें)
public static bool IsOfGenericType(this Type typeToCheck, Type genericType)
{
Type concreteType;
return typeToCheck.IsOfGenericType(genericType, out concreteType);
}
public static bool IsOfGenericType(this Type typeToCheck, Type genericType, out Type concreteGenericType)
{
while (true)
{
concreteGenericType = null;
if (genericType == null)
throw new ArgumentNullException(nameof(genericType));
if (!genericType.IsGenericTypeDefinition)
throw new ArgumentException("The definition needs to be a GenericTypeDefinition", nameof(genericType));
if (typeToCheck == null || typeToCheck == typeof(object))
return false;
if (typeToCheck == genericType)
{
concreteGenericType = typeToCheck;
return true;
}
if ((typeToCheck.IsGenericType ? typeToCheck.GetGenericTypeDefinition() : typeToCheck) == genericType)
{
concreteGenericType = typeToCheck;
return true;
}
if (genericType.IsInterface)
foreach (var i in typeToCheck.GetInterfaces())
if (i.IsOfGenericType(genericType, out concreteGenericType))
return true;
typeToCheck = typeToCheck.BaseType;
}
}
यहाँ एक परीक्षण बुनियादी (बुनियादी) कार्यक्षमता प्रदर्शित करने के लिए है:
[Test]
public void SimpleGenericInterfaces()
{
Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IEnumerable<>)));
Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IQueryable<>)));
Type concreteType;
Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IEnumerable<>), out concreteType));
Assert.AreEqual(typeof(IEnumerable<string>), concreteType);
Assert.IsTrue(typeof(Table<string>).IsOfGenericType(typeof(IQueryable<>), out concreteType));
Assert.AreEqual(typeof(IQueryable<string>), concreteType);
}
return list.GetType().IsGenericType;