GON*_*ale 20 .net c# reflection
我想确定通用对象类型("T")方法类型参数是否是集合类型.我通常会将T通过作为Generic.List发送,但它可以是任何集合类型,因为它在辅助函数中使用.
我是否最好测试它是否实现IEnumerable <T>?
如果是这样,代码会是什么样的?
更新格林尼治标准时间14:17 + 10可能会扩展到这里的解决方案(但是如果列表派生的话,它只适用于List <T>而不是IEnumerable <T>)
T currentObj;
// works if currentObj is List<T>
currentObj.GetType().GetGenericTypeDefinition() == typeof(List<>)
// does not work if currentObj is List<T>
currentObj.GetType().GetGenericTypeDefinition() == typeof(IEnumerable<>)
Run Code Online (Sandbox Code Playgroud)
thi*_*eek 34
这将是最简单的检查..
if(Obj is ICollection)
{
//Derived from ICollection
}
else
{
//Not Derived from ICollection
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*upp 15
您可以将Type.GetInterface()与受损名称一起使用.
private bool IsTAnEnumerable<T>(T x)
{
return null != typeof(T).GetInterface("IEnumerable`1");
}
Run Code Online (Sandbox Code Playgroud)
为了在运行时获取T的实际类型,可以使用typeof(T)表达式.从那里,普通类型比较运算符将起到作用
bool isEnumerable = typeof(IEnumerable<int>).IsAssignableFrom(typeof(T));
Run Code Online (Sandbox Code Playgroud)
完整代码示例:
static bool Foo<T>()
{
return typeof(IEnumerable<int>).IsAssignableFrom(typeof(T));
}
Foo<List<T>>(); // true
Foo<int>(); // false
Run Code Online (Sandbox Code Playgroud)
就个人而言,我倾向于使用我自己编写的方法,TryGetInterfaceGenericParameters
我在下面发布了这个方法.以下是如何在您的情况下使用它:
object currentObj = ...; // get the object
Type[] typeArguments;
if (currentObj.GetType().TryGetInterfaceGenericParameters(typeof(IEnumerable<>), out typeArguments))
{
var innerType = typeArguments[0];
// currentObj implements IEnumerable<innerType>
}
else
{
// The type does not implement IEnumerable<T> for any T
}
Run Code Online (Sandbox Code Playgroud)
重要的是要注意你传入typeof(IEnumerable<>)
,而不是 typeof(IEnumerable)
(这是一个完全不同的类型),也不 typeof(IEnumerable<T>)
是任何T
(如果你已经知道T
,你不需要这种方法).当然这适用于任何通用接口,例如您也可以使用typeof(IDictionary<,>)
(但不能 typeof(IDictionary)
).
/// <summary>
/// Determines whether the current type is or implements the specified generic interface, and determines that
/// interface's generic type parameters.</summary>
/// <param name="type">
/// The current type.</param>
/// <param name="interface">
/// A generic type definition for an interface, e.g. typeof(ICollection<>) or typeof(IDictionary<,>).</param>
/// <param name="typeParameters">
/// Will receive an array containing the generic type parameters of the interface.</param>
/// <returns>
/// True if the current type is or implements the specified generic interface.</returns>
public static bool TryGetInterfaceGenericParameters(this Type type, Type @interface, out Type[] typeParameters)
{
typeParameters = null;
if (type.IsGenericType && type.GetGenericTypeDefinition() == @interface)
{
typeParameters = type.GetGenericArguments();
return true;
}
var implements = type.FindInterfaces((ty, obj) => ty.IsGenericType && ty.GetGenericTypeDefinition() == @interface, null).FirstOrDefault();
if (implements == null)
return false;
typeParameters = implements.GetGenericArguments();
return true;
}
Run Code Online (Sandbox Code Playgroud)