54 Stimmen

Ermitteln, ob die Sammlung vom Typ IEnumerable<T> ist

Wie lässt sich feststellen, ob ein Objekt vom Typ IEnumerable <T> ist?

Code:

namespace NS {
    class Program {
        static IEnumerable<int> GetInts() {
            yield return 1;
        }
        static void Main() {
            var i = GetInts();
            var type = i.GetType();
            Console.WriteLine(type.ToString());
        }
    }
}

Ausgabe:

NS.1.Program+<GetInts>d__0

Wenn ich GetInts so ändere, dass es IList zurückgibt, ist alles in Ordnung die Ausgabe ist:

 System.Collections.Generic.List`1[System.Int32]

Und das Ergebnis ist falsch:

namespace NS {
    class Program {
        static IEnumerable<int> GetInts() {
            yield return 1;
        }
        static void Main() {
            var i = GetInts();
            var type = i.GetType();
            Console.WriteLine(type.Equals(typeof(IEnumerable<int>)));
        }
    }
}

111voto

Marc Gravell Punkte 970173

Wenn Sie die Sammlung dann einfach as :

var asEnumerable = i as IEnumerable<int>;
if(asEnumerable != null) { ... }

Ich gehe jedoch davon aus (aufgrund des Beispiels), dass Sie eine Type :

En Objekt wird nie vom Typ "von" sein IEnumerable<int> - aber es könnte implementieren Das würde ich erwarten:

if(typeof(IEnumerable<int>).IsAssignableFrom(type)) {...}

tun würde. Wenn Sie nicht wissen, welche T ( int in der obigen Abbildung), dann prüfen Sie alle implementierten Schnittstellen:

static Type GetEnumerableType(Type type) {
    if (type.IsInterface && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        return type.GetGenericArguments()[0];
    foreach (Type intType in type.GetInterfaces()) {
        if (intType.IsGenericType
            && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) {
            return intType.GetGenericArguments()[0];
        }
    }
    return null;
}

und anrufen:

Type t = GetEnumerableType(type);

wenn dies null ist, ist es nicht IEnumerable<T> für jede T - sonst prüfen t .

20voto

Serge Intern Punkte 2309

Da IEnumerable<T> von IEnumerable (nicht generisch) erben und wenn Sie nicht wissen müssen, wann ein Typ nur IEnumerable und nicht IEnumerable<T> ist, können Sie verwenden:

if (typeof(IEnumerable).IsAssignableFrom(srcType))

14voto

Mark Rendle Punkte 8989

Dieselbe Technik wie bei der Antwort von Marc, aber Linqier:

namespace NS
{
    class Program
    {
        static IEnumerable<int> GetInts()
        {
            yield return 1;
        }

        static void Main()
        {
            var i = GetInts();
            var type = i.GetType();
            var isEnumerableOfT = type.GetInterfaces()
                .Any(ti => ti.IsGenericType
                     && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>));
            Console.WriteLine(isEnumerableOfT);
        }
    }
}

7voto

Piotr Justyna Punkte 4612

Wie bestimmt man, ob ein Objekt vom Typ IEnumerable <T> ist?

Bitte verwenden Sie diese feine, sehr kleine, generische Erweiterungsmethode, um festzustellen, ob ein Objekt die Schnittstelle IEnumerable implementiert. Sie erweitert die Objekt Typs, so dass Sie es mit jeder Instanz eines beliebigen Objekts ausführen können, das Sie verwenden.

public static class CollectionTestClass
{
    public static Boolean IsEnumerable<T>(this Object testedObject)
    {
        return (testedObject is IEnumerable<T>);
    }
}

4voto

Heinzi Punkte 157917

i ist vom Typ NS.1.Program+<GetInts>d__0 die ein Untertyp de IEnumerable<int> . Sie können also entweder

if (i is IEnumerable<int>) { ... }

o IsAssignableFrom (wie in Marcs Antwort).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X