C# 如何检查给定值是否为通用列表?
检查给定对象是否为列表或是否可以强制转换为列表的最佳方法是什么?最好的方法可能是执行以下操作:C# 如何检查给定值是否为通用列表?,c#,reflection,list,generics,C#,Reflection,List,Generics,检查给定对象是否为列表或是否可以强制转换为列表的最佳方法是什么?最好的方法可能是执行以下操作: public bool IsList(object value) { Type type = value.GetType(); // Check if type is a generic list of any type } 这将为您提供最大的灵活性,并允许您使用实现IList接口的许多不同类型。bool isList=o.GetType().IsGe
public bool IsList(object value)
{
Type type = value.GetType();
// Check if type is a generic list of any type
}
这将为您提供最大的灵活性,并允许您使用实现IList
接口的许多不同类型。bool isList=o.GetType().IsGenericType
IList list = value as IList;
if (list != null)
{
// use list in here
}
&&o.GetType().GetGenericTypeDefinition()==typeof(IList));
公共布尔IsList(对象值){
返回值为IList
||IsGenericList(值);
}
公共bool IsGenericList(对象值){
var type=value.GetType();
返回类型。IsGenericType
&&typeof(List)=type.GetGenericTypeDefinition();
}
对于喜欢使用扩展方法的朋友:
public bool IsList(object value) {
return value is IList
|| IsGenericList(value);
}
public bool IsGenericList(object value) {
var type = value.GetType();
return type.IsGenericType
&& typeof(List<>) == type.GetGenericTypeDefinition();
}
根据维克多·罗德里格斯的回答,我们可以设计出另一种泛型方法。事实上,原始解决方案可以简化为两行:
if(o.IsGenericList())
{
//...
}
公共静态bool isgenericslist(此对象值)
{
var t=Value.GetType();
返回t.IsGenericType&&t.GetGenericTypeDefinition()==typeof(列表);
}
公共静态bool IsGenericList(此对象值)
{
var t=Value.GetType();
返回t.IsGenericType&&t.GetGenericTypeDefinition()==typeof(列表);
}
以下是一个在.NET标准中工作并针对接口工作的实现:
public static bool IsGenericList(this object Value)
{
var t = Value.GetType();
return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<>);
}
public static bool IsGenericList<T>(this object Value)
{
var t = Value.GetType();
return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<T>);
}
以下是测试(xunit):
[事实]
public void实现通用接口列表有效接口类型()
{
var list=新列表();
True(list.GetType().ImplementsGenericInterface(typeof(IList));
True(list.GetType().ImplementsGenericInterface(typeof(IEnumerable)));
True(list.GetType().ImplementsGenericInterface(typeof(IReadOnlyList));
}
[事实]
public void实现通用接口列表不无效InterfaceTypes()
{
var list=新列表();
Assert.False(list.GetType().ImplementsGenericInterface(typeof(string)));
Assert.False(list.GetType().ImplementsGenericInterface(typeof(IDictionary)));
Assert.False(list.GetType().ImplementsGenericInterface(typeof(IComparable));
Assert.False(list.GetType().ImplementsGenericInterface(typeof(DateTime)));
}
我正在使用以下代码:
[Fact]
public void ImplementsGenericInterface_List_IsValidInterfaceTypes()
{
var list = new List<string>();
Assert.True(list.GetType().ImplementsGenericInterface(typeof(IList<>)));
Assert.True(list.GetType().ImplementsGenericInterface(typeof(IEnumerable<>)));
Assert.True(list.GetType().ImplementsGenericInterface(typeof(IReadOnlyList<>)));
}
[Fact]
public void ImplementsGenericInterface_List_IsNotInvalidInterfaceTypes()
{
var list = new List<string>();
Assert.False(list.GetType().ImplementsGenericInterface(typeof(string)));
Assert.False(list.GetType().ImplementsGenericInterface(typeof(IDictionary<,>)));
Assert.False(list.GetType().ImplementsGenericInterface(typeof(IComparable<>)));
Assert.False(list.GetType().ImplementsGenericInterface(typeof(DateTime)));
}
public bool IsList(Type)=>IsGeneric(Type)&(
(type.GetGenericTypeDefinition()==typeof(列表))
||(type.GetGenericTypeDefinition()==typeof(IList))
);
我认为您需要调用GetType(),例如value.GetType().GetGenericArguments().Length>0这不起作用-我得到以下异常-值是IList,使用泛型类型“System.Collections.generic.IList”需要“1”类型参数,您需要使用System.Collections添加;在源文件的顶部。我建议的IList接口不是通用版本(因此需要进行第二次检查),您是对的。这很有魅力。我在我的手表窗口中测试这个,忘记了所有缺少的名称空间。我更喜欢这个解决方案,非常简单。这不起作用。我猜是4.0版本的IList!=伊里斯特?无论如何,我必须检查它是否是泛型和IEnumerable,然后检查我想要检查的属性“Count”是否存在。我想这是WCF将所有列表转换为T[]的部分原因。@Edza不正确。这通常是有效的,因为List
和observateCollection
实现IList
。这不会检查它是否是所要求的通用列表。也许您可以在这里找到.Net Core的答案。这需要稍微修改为返回oType.GetTypeInfo().IsGenericType&&oType.GetGenericTypeDefinition()==typeof(List)代码>就像一个魅力!如果您只有类型而不是对象,这将适用于您!谢谢检查IList是否更安全?
public static bool IsGenericList(this object o)
{
var oType = o.GetType();
return (oType.IsGenericType && (oType.GetGenericTypeDefinition() == typeof(List<>)));
}
if(o.IsGenericList())
{
//...
}
public static bool IsGenericList(this object Value)
{
var t = Value.GetType();
return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<>);
}
public static bool IsGenericList<T>(this object Value)
{
var t = Value.GetType();
return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(List<T>);
}
public static bool ImplementsGenericInterface(this Type type, Type interfaceType)
{
return type
.GetTypeInfo()
.ImplementedInterfaces
.Any(x => x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == interfaceType);
}
[Fact]
public void ImplementsGenericInterface_List_IsValidInterfaceTypes()
{
var list = new List<string>();
Assert.True(list.GetType().ImplementsGenericInterface(typeof(IList<>)));
Assert.True(list.GetType().ImplementsGenericInterface(typeof(IEnumerable<>)));
Assert.True(list.GetType().ImplementsGenericInterface(typeof(IReadOnlyList<>)));
}
[Fact]
public void ImplementsGenericInterface_List_IsNotInvalidInterfaceTypes()
{
var list = new List<string>();
Assert.False(list.GetType().ImplementsGenericInterface(typeof(string)));
Assert.False(list.GetType().ImplementsGenericInterface(typeof(IDictionary<,>)));
Assert.False(list.GetType().ImplementsGenericInterface(typeof(IComparable<>)));
Assert.False(list.GetType().ImplementsGenericInterface(typeof(DateTime)));
}
public bool IsList(Type type) => IsGeneric(type) && (
(type.GetGenericTypeDefinition() == typeof(List<>))
|| (type.GetGenericTypeDefinition() == typeof(IList<>))
);