如何确定对象是否是任何类型的列表?

时间:2016-12-22 07:49:39

标签: c# unity3d types

我正在编写一个脚本,我可以提供各种对象并告诉它以各种方式修改它们。这适用于许多类型,但我不知道如何处理列表(和其他集合)。 这不起作用:

List<Transform> transformList = new List<Transform>();

void MyFunction( object o ) {
    if( o.GetType() == typeof( int ) DoIntStuff(); //Easy
    else if( o.GetType() == typeof( Color ) DoColorStuff(); //Also Easy
    else if( o.GetType() == typeof( List<> ) ) DoListStuff(); //Not as easy :(
}

void Start() {
    MyFunction( transformList );
}

我无法做到

typeof( List<T> )

因为T当然不存在。

typeof( List<object> ) 

也不起作用。

那么我怎样才能知道我所拥有的是否是任何类型的列表?

4 个答案:

答案 0 :(得分:1)

为什么不测试对象是否实现&#34; IEnumerable&#34;然后检查集合中的类型(对于genric集合),如下所示:

IEnumerable tempList = o as IEnumerable;
        if (tempList != null)
        {
            IEnumerable<DumyClass> items = tempList.OfType<DumyClass>();

            if(items.Count() != 0)
            {
                //Then handle the list of the specific type as needed.
            }            
        }

如果只需要列表类型,请检查&#34; IList&#34;如下:

IList tempList = o as IList;

        if (tempList != null)
        {
                //Then handle the list as needed.
        }

希望这很有用。

答案 1 :(得分:1)

如果你只是想检查它是否是一个List我会选择@Ali Ezzat Odeh方法并且只是检查

else if(o is IList) DoListStuff();

如果您需要查找包含不同元素列表的包含类型,可以尝试使用以下扩展方法:

    public static class TypeExtensions 
    {
            /// <summary>
            /// Gets the inner type of the given type, if it is an Array or has generic arguments. 
            /// Otherwise NULL.
            /// </summary>
            public static Type GetInnerListType(this Type source)
            {
                Type innerType = null;

                if (source.IsArray)
                {
                    innerType = source.GetElementType();
                }
                else if (source.GetGenericArguments().Any())
                {
                    innerType = source.GetGenericArguments()[0];
                }

                return innerType;
            }
     }

您可以像

一样使用它
else if(o.GetType().GetInnerListType() == typeof(Transform)) DoTransformListStuff();

扩展程序处理各种列表,也处理数组。在我看来,最好不要只查找List的类型。这样,如果您要进入UI,可以使用替换容器替换列表,例如使用数组表示性能或使用可观察集合。它将在未来为您留下更多的设计选择,您可以更好地适应。

答案 2 :(得分:0)

假设您要检查某个List<T>的类型是/ {继承T(而不仅仅是某些IList<T>的实现T),您可以使用以下扩展方法:

public static class TypeExtensions
{
    public static bool IsGenericList(this Type type)
    {
        return type.GetGenericListItemType() != null;
    }

    public static Type GetGenericListItemType(this Type type)
    {
        while (type != null)
        {
            if (type.IsGenericType)
            {
                var genType = type.GetGenericTypeDefinition();
                if (genType == typeof(List<>))
                    return type.GetGenericArguments()[0];
            }
            type = type.BaseType;
        }
        return null;
    }
}

答案 3 :(得分:0)

据我所知,没有办法从Type对象中获取列表对象的“List”部分。这是因为根据代码,没有“List”类型,但实际上有许多不同的生成类型,它们对应于“List”在整个程序过程中接收的各种泛型。例如,如果您的程序包含以下内容:

var a = new List<bool>();
var b = new List<int>();
var c = new List<char>();

您编译的程序基本上包含以下类,每个类的代码中的T都替换为相应的类型:

List`1 // bool List
List`2 // int List
List`3 // char List

但是,你可以稍微欺骗它。由于通用名称将始终遵循上述模式,因此您可以使用该名称执行检查:

var list = new List<int>();
var type = list.GetType();
bool isList = list.GetType().Name.Split('`')[0] == "List";