5

オブジェクトが与えられ、次のことを行う必要がある状況があります。

  • そのオブジェクトが単一のオブジェクトかコレクション (配列、リストなど) かを判断します。
  • コレクションの場合は、リストをステップ実行します。

私がこれまでに持っているもの。IEnumerable のテストが機能しません。また、IEnumerable への変換は、非プリミティブ型に対してのみ機能します。

static bool IsIEnum<T>(T x)
{
    return null != typeof(T).GetInterface("IEnumerable`1");
}
static void print(object o)
{
    Console.WriteLine(IsIEnum(o));       // Always returns false
    var o2 = (IEnumerable<object>)o;     // Exception on arrays of primitives
    foreach(var i in o2) {
        Console.WriteLine(i);
    }
}
public void Test()
{
    //int [] x = new int[]{1,2,3,4,5,6,7,8,9};
    string [] x = new string[]{"Now", "is", "the", "time..."};
    print(x);       
}

誰でもこれを行う方法を知っていますか?

4

3 に答える 3

10

オブジェクトが非ジェネリックIEnumerableインターフェイスに変換可能かどうかを確認するだけで十分です。

var collection = o as IEnumerable;
if (collection != null)
{
    // It's enumerable...
    foreach (var item in collection)
    {
        // Static type of item is System.Object.
        // Runtime type of item can be anything.
        Console.WriteLine(item);
    }
}
else
{
    // It's not enumerable...
}

IEnumerable<T>それ自体が実装するIEnumerableため、これはジェネリック型と非ジェネリック型の両方で機能します。ジェネリック インターフェイスの代わりにこのインターフェイスを使用すると、ジェネリック インターフェイスの差異に関する問題が回避IEnumerable<T>されIEnumerable<object>ます。

この質問では、ジェネリック インターフェイスの差異についてさらに詳しく説明します: Generic Variance in C# 4.0

于 2013-02-20T16:24:04.270 に答える
0

次のコードを使用します。

Type t = typeof(System.Collections.IEnumerable);

Console.WriteLine(t.IsAssignableFrom(T)); //returns true for collentions
于 2013-02-20T16:31:27.133 に答える
0

の汎用バージョンを使用しないでくださいIEnumerable

static void print(object o)
{
    Console.WriteLine(IsIEnum(o));       // Always returns false
    var o2 = o as IEnumerable;     // Exception on arrays of primitives
    if(o2 != null) {
      foreach(var i in o2) {
        Console.WriteLine(i);
      }
    } 
}

このようにすると、で使用できるいくつかの型が失われforeachます。のコレクションとして使用できるオブジェクトは、実装するforeach必要はありません。実装IEnumerableする必要があるだけで、プロパティとメソッドGetEnumeratorを持つ型を返す必要があります。CurrentMoveNext

コレクションが型付けされていて、さまざまな種類のコレクションをサポートする必要があるだけの場合

static void print<T>(T o) {
    //Not a collection
}

static void print<T>(IEnumerable<T> o) {
   foreach(var i in o2) {
        Console.WriteLine(i);
   }
}

この場合、メソッドのオーバーロードの解決により、オブジェクトがコレクションであるかどうかに応じて適切なメソッドが選択されます (この場合は、実装によって定義されますIEnumerable<T>) 。

于 2013-02-20T16:24:19.663 に答える