wake-up-neo.com

Stellen Sie fest, ob die Auflistung vom Typ IEnumerable <T> ist

Wie können Sie feststellen, ob das 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 dahingehend ändere, dass IList zurückgegeben wird, ist alles in Ordnung. Die Ausgabe ist:

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

Und das gibt falsch zurück:

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>)));
        }
    }
}
49
Valentin

Wenn Sie die collection meinen, dann as:

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

Ich gehe jedoch davon aus (aus dem Beispiel), dass Sie eine Type haben:

Das object wird niemals "vom" Typ IEnumerable<int> sein - aber es könnte implementieren Ich würde das erwarten:

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

würdest du. Wenn Sie die T (int oben) nicht kennen, überprüfen Sie alle implementierten Schnittstellen:

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

und Ruf an:

Type t = GetEnumerableType(type);

wenn dies null ist, ist es nicht IEnumerable<T> für eine T - ansonsten t.

99
Marc Gravell

Dieselbe Technik wie Marc's Antwort, 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);
        }
    }
}
14
Mark Rendle

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

if (typeof(IEnumerable).IsAssignableFrom(srcType))
13
Serge Intern

So stellen Sie fest, ob das Objekt vom Typ .__ ist. IEnumerable <T>?

Sie können diese feine, sehr kleine, generische Erweiterungsmethode verwenden, um zu bestimmen, ob ein Objekt die IEnumerable-Schnittstelle implementiert. Es erweitert den Typ Object , sodass 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>);
    }
}
7
Piotr Justyna

i ist vom Typ NS.1.Program+<GetInts>d__0, dh ein Untertyp von IEnumerable<int> Sie können also beide verwenden

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

oder IsAssignableFrom (wie in Marc's Antwort).

3
Heinzi

Sie können das Schlüsselwort is verwenden.

[TestFixture]
class Program
{
    static IEnumerable<int> GetInts()
    {
        yield return 1;
    }

    [Test]
    static void Maasd()
    {
        var i = GetInts();
        Assert.IsTrue(i is IEnumerable<int>);
    }
}
1
tster
0
SwDevMan81