关于c#:将对象转换为集合

Convert Object to Collection

我遇到一个需要给我物体的情况,需要:

  • 确定该对象是单个对象还是集合(数组,列表等)
  • 如果是集合,请遍历列表。

到目前为止我所拥有的。测试IEnumerable不起作用。并且到IEnumerable的转换仅适用于非原始类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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);      
}

有人知道该怎么做吗?


检查对象是否可转换为非通用IEnumerable接口就足够了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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>

此问题将更详细地讨论通用接口差异:C#4.0中的通用方差


使用以下代码:

1
2
3
Type t = typeof(System.Collections.IEnumerable);

Console.WriteLine(t.IsAssignableFrom(T)); //returns true for collentions


请勿使用IEnumerable

的通用版本

1
2
3
4
5
6
7
8
9
10
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,后者又需要返回具有Current属性和MoveNext的类型。方法

如果键入了集合,而您只需要支持其他种类的集合,就可以这样做

1
2
3
4
5
6
7
8
9
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>定义)为您选择正确的方法。