C#泛型列表<T>如何获取T的类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1043755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# generic list <T> how to get the type of T?
提问by
I'm working on a reflection project, and now I'm stuck.
我正在做一个反射项目,现在我被卡住了。
If I have an object of myclass
that can hold a List<SomeClass>
, does anyone know how to get the type as in the code below if the property myclass.SomList
is empty?
如果我有一个myclass
可以容纳 a的对象,List<SomeClass>
如果属性myclass.SomList
为空,有没有人知道如何获取下面代码中的类型?
List<myclass> myList = dataGenerator.getMyClasses();
lbxObjects.ItemsSource = myList;
lbxObjects.SelectionChanged += lbxObjects_SelectionChanged;
private void lbxObjects_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Reflect();
}
Private void Reflect()
{
foreach (PropertyInfo pi in lbxObjects.SelectedItem.GetType().GetProperties())
{
switch (pi.PropertyType.Name.ToLower())
{
case "list`1":
{
// This works if the List<T> contains one or more elements.
Type tTemp = GetGenericType(pi.GetValue(lbxObjects.SelectedItem, null));
// but how is it possible to get the Type if the value is null?
// I need to be able to create a new object of the type the generic list expect.
// Type type = pi.getType?? // how to get the Type of the class inside List<T>?
break;
}
}
}
}
private Type GetGenericType(object obj)
{
if (obj != null)
{
Type t = obj.GetType();
if (t.IsGenericType)
{
Type[] at = t.GetGenericArguments();
t = at.First<Type>();
}
return t;
}
else
{
return null;
}
}
采纳答案by Marc Gravell
Type type = pi.PropertyType;
if(type.IsGenericType && type.GetGenericTypeDefinition()
== typeof(List<>))
{
Type itemType = type.GetGenericArguments()[0]; // use this...
}
More generally, to support any IList<T>
, you need to check the interfaces:
更一般地,要支持 any IList<T>
,您需要检查接口:
foreach (Type interfaceType in type.GetInterfaces())
{
if (interfaceType.IsGenericType &&
interfaceType.GetGenericTypeDefinition()
== typeof(IList<>))
{
Type itemType = type.GetGenericArguments()[0];
// do something...
break;
}
}
回答by GaryJL
Marc's answer is the approach I use for this, but for simplicity (and a friendlier API?) you can define a property in the collection base class if you have one such as:
Marc 的答案是我为此使用的方法,但为了简单起见(和更友好的 API?),如果您有以下属性,您可以在集合基类中定义一个属性:
public abstract class CollectionBase<T> : IList<T>
{
...
public Type ElementType
{
get
{
return typeof(T);
}
}
}
I have found this approach useful, and is easy to understand for any newcomers to generics.
我发现这种方法很有用,并且对于泛型的任何新手来说都很容易理解。
回答by Colonel Panic
Given an object which I suspect to be some kind of IList<>
, how can I determine of whatit's an IList<>
?
给定一个对象,我怀疑是某种的IList<>
,我怎么能确定的东西它是一个IList<>
?
Here's a reliable solution. My apologies for length - C#'s introspection API makes this suprisingly difficult.
这是一个可靠的解决方案。我很抱歉,因为 C# 的内省 API 使这变得非常困难。
/// <summary>
/// Test if a type implements IList of T, and if so, determine T.
/// </summary>
public static bool TryListOfWhat(Type type, out Type innerType)
{
Contract.Requires(type != null);
var interfaceTest = new Func<Type, Type>(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>) ? i.GetGenericArguments().Single() : null);
innerType = interfaceTest(type);
if (innerType != null)
{
return true;
}
foreach (var i in type.GetInterfaces())
{
innerType = interfaceTest(i);
if (innerType != null)
{
return true;
}
}
return false;
}
Example usage:
用法示例:
object value = new ObservableCollection<int>();
Type innerType;
TryListOfWhat(value.GetType(), out innerType).Dump();
innerType.Dump();
Returns
退货
True
typeof(Int32)
回答by Colonel Panic
Given an object which I suspect to be some kind of IList<>
, how can I determine of whatit's an IList<>
?
给定一个对象,我怀疑是某种的IList<>
,我怎么能确定的东西它是一个IList<>
?
Here's the gutsy solution. It assumes you have the actual object to test (rather than a Type
).
这是勇敢的解决方案。它假设您有要测试的实际对象(而不是 a Type
)。
public static Type ListOfWhat(Object list)
{
return ListOfWhat2((dynamic)list);
}
private static Type ListOfWhat2<T>(IList<T> list)
{
return typeof(T);
}
Example usage:
用法示例:
object value = new ObservableCollection<DateTime>();
ListOfWhat(value).Dump();
Prints
印刷
typeof(DateTime)