如何从 .net 中的 Array Type 获取 Array Item Type
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4129831/
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
How do I get the Array Item Type from Array Type in .net
提问by Preet Sangha
Say I have an System.String[]type object. I can query the type object to determine if it is an array
假设我有一个System.String[]类型对象。我可以查询类型对象以确定它是否是一个数组
Type t1 = typeof(System.String[]);
bool isAnArray = t1.IsArray; // should be true
However how do I get a type object of the array item from t1
但是,如何从 t1 获取数组项的类型对象
Type t2 = ....; // should be typeof(System.String)
回答by Ani
You can use the instance method Type.GetElementTypefor this purpose.
Type.GetElementType为此,您可以使用实例方法。
Type t2 = t1.GetElementType();
[Returns] the type of the object encompassed or referred to by the current array, pointer, or reference type, or null if the current Type is not an array or a pointer, or is not passed by reference, or represents a generic type or a type parameter in the definition of a generic type or generic method.
[返回] 当前数组、指针或引用类型包含或引用的对象的类型,如果当前 Type 不是数组或指针,或者不是通过引用传递,或者表示泛型类型,则返回 null泛型类型或泛型方法定义中的类型参数。
回答by drzaus
Thanks to @psaxton commentpointing out the difference between Array and other collections. As an extension method:
感谢@psaxton评论指出 Array 和其他集合之间的区别。作为扩展方法:
public static class TypeHelperExtensions
{
/// <summary>
/// If the given <paramref name="type"/> is an array or some other collection
/// comprised of 0 or more instances of a "subtype", get that type
/// </summary>
/// <param name="type">the source type</param>
/// <returns></returns>
public static Type GetEnumeratedType(this Type type)
{
// provided by Array
var elType = type.GetElementType();
if (null != elType) return elType;
// otherwise provided by collection
var elTypes = type.GetGenericArguments();
if (elTypes.Length > 0) return elTypes[0];
// otherwise is not an 'enumerated' type
return null;
}
}
Usage:
用法:
typeof(Foo).GetEnumeratedType(); // null
typeof(Foo[]).GetEnumeratedType(); // Foo
typeof(List<Foo>).GetEnumeratedType(); // Foo
typeof(ICollection<Foo>).GetEnumeratedType(); // Foo
typeof(IEnumerable<Foo>).GetEnumeratedType(); // Foo
// some other oddities
typeof(HashSet<Foo>).GetEnumeratedType(); // Foo
typeof(Queue<Foo>).GetEnumeratedType(); // Foo
typeof(Stack<Foo>).GetEnumeratedType(); // Foo
typeof(Dictionary<int, Foo>).GetEnumeratedType(); // int
typeof(Dictionary<Foo, int>).GetEnumeratedType(); // Foo, seems to work against key
回答by Shimmy Weitzhandler
Thanks to @drzausfor his nice answer, but it can be compressed to a oneliner (plus check for nulls and IEnumerabletype):
感谢@drzaus的好回答,但它可以压缩为一个单行(加上检查nulls 和IEnumerable类型):
public static Type GetEnumeratedType(this Type type) =>
type?.GetElementType()
?? typeof(IEnumerable).IsAssignableFrom(type)
? type.GenericTypeArguments.FirstOrDefault()
: null;
Added nullcheckers to avoid exception, maybe I shouldn't (feel free to remove the Null Conditional Operators).
Also added a filter so the function only works on collections, not any generic types.
添加了null检查器以避免异常,也许我不应该(随意删除Null Conditional Operators)。还添加了一个过滤器,因此该函数仅适用于集合,而不适用于任何泛型类型。
And bear in mind that this could also be fooled by implemented subclasses that change the subject of the collection and the implementor decided to move the collection's generic-type-argument to a later position.
请记住,这也可能被实现的子类所愚弄,这些子类改变了集合的主题,并且实现者决定将集合的泛型类型参数移到后面的位置。

