web-dev-qa-db-ja.com

コレクションのタイプがIEnumerable <T>かどうかを判別

オブジェクトのタイプがIEnumerable <T>かどうかを確認する方法は?

コード:

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());
        }
    }
}

出力:

NS.1.Program+<GetInts>d__0

GetIntsを変更してIListを返す場合、出力は次のようになります。

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

そして、これはfalseを返します:

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

collectionの場合、as

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

ただし、私は(例から)Typeがあると想定しています。

objectIEnumerable<int>型になることはありませんが、implementそれ;私はそれを期待します:

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

するだろう。 T(上記のint)がわからない場合は、実装されているすべてのインターフェースを確認してください。

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

そして呼び出す:

Type t = GetEnumerableType(type);

これがnullの場合、TIEnumerable<T>ではありません。それ以外の場合はtを確認してください。

101
Marc Gravell

IEnumerable <T>はIEnumerable(ジェネリックではない)を継承するため、型がIEnumerable <T>ではなくIEnumerable <T>ではないことを知る必要がない場合は、次のように使用できます。

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

マルクの答えと同じテクニックですが、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

オブジェクトのタイプがIEnumerable <T>かどうかを確認する方法は?

この細かい超小型の汎用拡張メソッドを使用して、オブジェクトがIEnumerableインターフェイスを実装しているかどうかを判断してください。 Objectタイプを拡張するため、使用しているオブジェクトのインスタンスを使用して実行できます。

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

iはタイプNS.1.Program+<GetInts>d__0、これはサブタイプIEnumerable<int>。したがって、どちらかを使用できます

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

またはIsAssignableFrom(Marcの答えのように)。

3
Heinzi

isキーワードを使用できます。

[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