我正在编写一个脚本,我可以提供各种对象并告诉它以各种方式修改它们。这适用于许多类型,但我不知道如何处理列表(和其他集合)。 这不起作用:
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> )
也不起作用。
那么我怎样才能知道我所拥有的是否是任何类型的列表?
答案 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";