C# 如何判断类型是列表、数组还是IEnumerable或

C# 如何判断类型是列表、数组还是IEnumerable或,c#,reflection,C#,Reflection,给定一个类型对象,测试它是否实际上是一个对象列表的最简单方法是什么?例如数组或IEnumerable/IEnumerable。检查typeof(IEnumerable)。IsAssignableFrom(type) 每个集合类型,包括数组和IEnumerable,都实现了IEnumerable简单。最简单的方法是: IList<T> listTest = null; try{ listTest = ((IList<T>)yourObject); } catch

给定一个
类型
对象,测试它是否实际上是一个对象列表的最简单方法是什么?例如数组或IEnumerable/IEnumerable。

检查
typeof(IEnumerable)。IsAssignableFrom(type)


每个集合类型,包括数组和
IEnumerable
,都实现了
IEnumerable

简单。最简单的方法是:

IList<T> listTest = null;

try{
     listTest = ((IList<T>)yourObject);
}
catch(Exception listException)
{
    //your object doesn't support IList and is not of type List<T>
}

IEnumerable<T> enumerableTest = null;

try{
     enumerableTest = ((IEnumerable<T>)yourObject);
}
catch(Exception enumerableException)
{
     //your object doesn't suport IEnumerable<T>;
}
IList listTest=null;
试一试{
listTest=((IList)yourObject);
}
捕获(异常listException)
{
//您的对象不支持IList,并且不是List类型
}
IEnumerable enumerableTest=null;
试一试{
enumerableTest=((IEnumerable)yourObject);
}
捕获(异常enumerableException)
{
//你的对象不支持IEnumerable;
}
==================================================

您也可以尝试这种不涉及多个try/catch块的方法。最好避免使用这些条件,因为每个条件实际上都是由运行时在运行时进行计算的。。。这是一个糟糕的代码(尽管有时无法避免)

Type t=yourObject.GetType();
如果(t是typeof(List))//对象类型是string、decimal等等。。。
{
//t是列表的类型。。。
}
else if(t是typeof(IEnumerable)
{
//t是IEnumerable类型的。。。
}
其他的
{
//t是另一种类型。
//使用反射来找到它。
}
typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType)

如果我们是从通用T.验证的话,这并不能完全回答这个问题,但我认为这是一个对那些登上这篇文章的人有用的代码

给定一个对象或IList,可以使用以下代码检查该对象是否为数组

IList<string> someIds = new string[0];
if (someIds is Array)
{
    // yes!
}

IList<string> someIds = new List<string>(0);
if (someIds is Array)
{
    // nop!
}
IList-someIds=新字符串[0];
if(someIds是数组)
{
//对!!
}
IList SomeId=新列表(0);
if(someIds是数组)
{
//不!
}

这里的区别在于,我们不是在处理任何
类型的
对象,而是在处理实际对象。

我建议使用模式匹配。 与此示例方法类似:

public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
{
    if (items == null)
        return true;

    if (items is T[] arr)
        return arr.Length == 0;

    return !items.Any();
}
public static bool为空(此IEnumerable items)
{
if(items==null)
返回true;
如果(项目为T[]arr)
返回arr.Length==0;
return!items.Any();
}

谢谢-我不得不排除
字符串
,因为这是一个
字符数组,我不想这样。:)也排除System.Xml.XmlText以及System.Xml.XmlNode的其他后代。注意:
IEnumerable
System.Collections.Generic中被识别命名空间,但要使用这段代码,还需要使用System.Collections添加
否则,我们会使用泛型类型IEnumerable requires 1 type参数得到编译错误
,Visual Studio甚至不建议使用此名称空间而不是执行
listTest=((IList)yourObject)捕获一个异常,你只需执行
你的对象是IList
哇,真是一团糟。这里至少有四件事情严重错误。(1) 捕获异常而不是使用
作为
。(2) 捕获
异常
而不是
InvalidCastException
。(3) 在第二个代码块中,认为C#
is
的工作方式与VB6
is
的工作方式相同——实际上
=
是正确的运算符,但它仍然会失败,因为(4)
GetType()
总是返回一个具体的类,从来没有像
IEnumerable
objType这样的接口。如果它是
int?
Nullable
不是
IEnumerable
数组,IsGenericType
将返回
true
,MatthiasBurger我测试了它返回的结果false@AlaMusleh它对int返回True?这不能回答问题,它处理的是对
类型进行分类,而不是对值进行分类。在您的示例中,您已经知道它是
IEnumerable
,因为这是参数类型。
typeof(IEnumerable<object>).IsAssignableFrom(propertyInfo.PropertyType)
IList<string> someIds = new string[0];
if (someIds is Array)
{
    // yes!
}

IList<string> someIds = new List<string>(0);
if (someIds is Array)
{
    // nop!
}
public static bool IsNullOrEmpty<T>(this IEnumerable<T> items)
{
    if (items == null)
        return true;

    if (items is T[] arr)
        return arr.Length == 0;

    return !items.Any();
}