Angenommen, ich habe ein System.String[]
Typobjekt. Ich kann das Typobjekt abfragen, um festzustellen, ob es sich um ein Array handelt
Type t1 = typeof(System.String[]);
bool isAnArray = t1.IsArray; // should be true
Wie erhalte ich jedoch ein Typobjekt des Array-Elements von t1?
Type t2 = ....; // should be typeof(System.String)
.net
reflection
types
Preet Sangha
quelle
quelle
null
für dieArray
Klasse zurückgegeben." Es kann also nur beiT[]
Formularen funktionieren . Aber es scheint in Ordnung in meinem Test auf einemArray
vonArray.CreateInstance()
...Dank des Kommentars von @psaxton , der auf den Unterschied zwischen Array und anderen Sammlungen hinweist. Als Erweiterungsmethode:
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; } }
Verwendung:
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
quelle
IEnumerable
; Vielleicht hätte meine Verwendung von "Sammlungen" dann "aufzählbar" sein sollen?typeof(IEnumerable).IsAssinableFrom(type)
.IEnumerable
zum Beispiel einIObservable<T>
oder was auch immer ist. Ich würde den Methodentyp in ändernGetGenericType
.Vielen Dank an @drzaus für seine nette Antwort , die jedoch zu einem Oneliner komprimiert werden kann (plus Überprüfung auf
null
s undIEnumerable
Typ):public static Type GetEnumeratedType(this Type type) => type?.GetElementType() ?? typeof(IEnumerable).IsAssignableFrom(type) ? type.GenericTypeArguments.FirstOrDefault() : null;
Es wurden
null
Prüfer hinzugefügt , um Ausnahmen zu vermeiden, vielleicht sollte ich das nicht (zögern Sie nicht, die bedingten Nulloperatoren zu entfernen ). Außerdem wurde ein Filter hinzugefügt, damit die Funktion nur für Sammlungen funktioniert, nicht für generische Typen.Und denken Sie daran, dass dies auch durch implementierte Unterklassen getäuscht werden könnte, die das Thema der Sammlung ändern, und der Implementierer beschlossen hat, das generische Argument der Sammlung an eine spätere Position zu verschieben.
Konvertierte Antwort für C # 8 und Nullbarkeit:
public static Type GetEnumeratedType(this Type type) => ((type?.GetElementType() ?? (typeof(IEnumerable).IsAssignableFrom(type) ? type.GenericTypeArguments.FirstOrDefault() : null))!;
quelle