C#-获取通用列表的项目类型
获取通用列表包含的项目类型的最佳方法是什么?抓取集合中的第一个项并调用.GetType()很容易,但我不能总是确定集合中是否有项 希望这是有道理的 谢谢,C#-获取通用列表的项目类型,c#,collections,generics,C#,Collections,Generics,获取通用列表包含的项目类型的最佳方法是什么?抓取集合中的第一个项并调用.GetType()很容易,但我不能总是确定集合中是否有项 希望这是有道理的 谢谢, 桑尼你可以用这个方法来达到这个目的 List<Foo> myList = ... Type myListElementType = myList.GetType().GetGenericArguments().Single(); List myList=。。。 类型myListElementType=myList.GetTyp
桑尼你可以用这个方法来达到这个目的
List<Foo> myList = ...
Type myListElementType = myList.GetType().GetGenericArguments().Single();
List myList=。。。
类型myListElementType=myList.GetType().GetGenericArguments().Single();
对于更稳健的方法:
public static Type GetListType(object someList)
{
if (someList == null)
throw new ArgumentNullException("someList");
var type = someList.GetType();
if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(List<>))
throw new ArgumentException("Type must be List<>, but was " + type.FullName, "someList");
return type.GetGenericArguments()[0];
}
请注意,您甚至不需要someList
参数。此方法只是一个示例,说明了如果您已经使用了泛型方法,如何使用typeof
。仅当您无权访问t
标记(列表存储在非泛型类型变量中,例如一个类型化的IList
,对象
,等等)时,才需要使用反射方法。公共共享函数ListItemType(ListType作为System.Type)作为System.Type
如果不是ListType.IsGenericType,则
如果ListType.BaseType不是Nothing,也不是ListType.BaseType.IsGenericType,则
返回ListItemType(ListType.BaseType)
如果结束
其他的
返回ListType.GetGenericArguments.Single
如果结束
端函数
这是怎么回事,它全是静态的(例如,不需要实例)和快速的(无循环,不使用linq),很简单:)这些都适用于集合:
[System.Diagnostics.DebuggerHidden]
public static Type GetIndexedType(this ICollection poICollection)
{
PropertyInfo oPropertyInfo = poICollection == null ? null : poICollection.GetType().GetProperty("Item");
return oPropertyInfo == null ? null : oPropertyInfo.PropertyType;
}
[System.Diagnostics.DebuggerHidden]
public static Type GetEnumeratedType(this ICollection poICollection)
{
PropertyInfo oPropertyInfo = poICollection == null ? null : poICollection.GetType().GetMethod("GetEnumerator").ReturnType.GetProperty("Current");
return oPropertyInfo == null ? null : oPropertyInfo.PropertyType;
}
还有一些简单的单元测试:
[Test]
public void GetIndexedType()
{
Assert.AreEqual(null, ((ICollection)null).GetIndexedType());
Assert.AreEqual(typeof(int), (new List<int>()).GetIndexedType());
Assert.AreEqual(typeof(bool), (new SortedList<string, bool>()).GetIndexedType());
}
[Test]
public void GetEnumeratedType()
{
Assert.AreEqual(null, ((ICollection)null).GetEnumeratedType());
Assert.AreEqual(typeof(int), (new List<int>()).GetEnumeratedType());
Assert.AreEqual(typeof(KeyValuePair<string, bool>), (new SortedList<string, bool>()).GetEnumeratedType());
}
至于统计员:
[System.Diagnostics.DebuggerHidden]
public static Type GetEnumeratedType(this System.Collections.IEnumerator poIEnumerator)
{
PropertyInfo oPropertyInfo = poIEnumerator == null ? null : poIEnumerator.GetType().GetProperty("Current");
return oPropertyInfo == null ? null : oPropertyInfo.PropertyType;
}
以下是另一种适用于非泛型集合的方法:
static Type GetItemType(Type collectionType)
{
return collectionType.GetMethod("get_Item").ReturnType;
}
也就是说,获取foo[x]
的返回类型,其中foo
是指定的类型
示例:
// Generic type; prints System.Int32
Console.WriteLine(GetItemType(typeof(List<int>)));
// Non-generic type; prints System.String
Console.WriteLine(GetItemType(typeof(System.Collections.Specialized.StringCollection)));
带有
动态
void Foo(){
Type type GetTypeT(data as dynamic);
}
private static Type GetTypeT<T>(IEnumerable<T> data)
{
return typeof(T);
}
void Foo(){
类型GetTypeT(数据为动态);
}
私有静态类型GetTypeT(IEnumerable数据)
{
返回类型(T);
}
公共类型GetType(IEnumerable结果列表)
{
返回resultList.GetType().GetElementType();
}
这里有一个同样适用于派生类的解决方案
因为这门课:
public class SubList : List<int>
{ }
你对这种类型已经了解多少了?您可以提供一个示例上下文吗?如果T
标记在范围内(例如,在接受列表的方法中),您还可以使用typeof(T)
。如果列表
存储在object
类型的变量中,您将不得不使用上述方法。您今天早些时候没有回答另一个几乎完全相同的问题吗?@LukeH:是的,闪电确实击中了两次:)@Lambert:我不是降价专家,但我选择了一个块,然后单击“代码示例”图标。我建议你点击答案框右上角的橙色“?”来获取更多关于这个东西如何工作的信息。谢谢!!那真的很有帮助!天哪,错误处理得很好。您可能还需要添加可本地化的错误文本。;)美好的一个小问题-传递给new ArgumentException的参数是错误的。在这里,您的方法接受每个接口的非泛型版本,但只有当它们实际实现泛型版本时,才会按预期工作。如果你要满足这些要求,你最好让这些方法直接接受接口的通用版本。虽然这个代码片段可以解决这个问题,但确实有助于提高你文章的质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。还请尽量不要用解释性注释挤满您的代码,因为这会降低代码和解释的可读性!
// Generic type; prints System.Int32
Console.WriteLine(GetItemType(typeof(List<int>)));
// Non-generic type; prints System.String
Console.WriteLine(GetItemType(typeof(System.Collections.Specialized.StringCollection)));
public static Type GetItemType(this Type collectionType)
{
var types =
(from method in collectionType.GetMethods()
where method.Name == "get_Item"
select method.ReturnType
).Distinct().ToArray();
if (types.Length == 0)
return null;
if (types.Length != 1)
throw new Exception(string.Format("{0} has multiple item types", collectionType.FullName));
return types[0];
}
void Foo(){
Type type GetTypeT(data as dynamic);
}
private static Type GetTypeT<T>(IEnumerable<T> data)
{
return typeof(T);
}
public Type GetType(IEnumerable<object> resultList)
{
return resultList.GetType().GetElementType();
}
public class SubList : List<int>
{ }
public Type GetListItemType<T>(List<T> list)
{
Type type = list.GetType();
while (type != typeof(List<T>))
type = type.BaseType;
return type.GetGenericArguments().Single();
}
var list = new List<int>();
var subList = new SubList();
Console.WriteLine(GetListItemType(list)); // System.Int32
Console.WriteLine(GetListItemType(subList)); // System.Int32