将对象强制转换为IEnumerable<object>类型?

14

如何将一个 object 强制转换为 IEnumerable<object>

我知道该对象实现了 IEnumerable<object>,但是我不知道它的类型。它可能是一个数组,一个 List<T> 或其他什么。


我正在尝试让一个简单的测试用例工作:

static void Main(string[] args)
{
    object arr = new[] { 1, 2, 3, 4, 5 };
    foreach (var item in arr as IEnumerable<object>)
        Console.WriteLine(item);
    Console.ReadLine();
}

你想用它做什么?你能给我们举个例子吗? - Ani
@Ani:我有一个包含多种类型对象的Dictionary<string,object>。其中一些是可枚举的。我正在尝试找出如何在不知道它们确切类型的情况下循环遍历它们。 - mpen
2个回答

19

我遇到了协变不支持值类型的相同问题,我有一个实际类型为List<Guid>object,需要一个IEnumerable<object>。当仅使用IEnumerable不够用时,生成IEnumerable的一种方法是使用linq Cast方法。

((IEnumerable)lhsValue).Cast<object>()

16

如果没有具体的用例,很难回答这个问题,但是您可以将其简单地转换为非泛型的IEnumerable接口,这可能已经足够了。

为什么这通常适用于大多数被认为是“序列”的类型,有两个原因:

  1. "经典的".NET 1.x集合类实现了IEnumerable
  2. 泛型IEnumerable<T>接口继承自IEnumerable,因此对于System.Collections.Generic中的泛型集合类、LINQ序列等,转换应该可以正常工作。

编辑:

至于为什么您提供的示例不起作用:

  1. C# 3中无法使用这种方式,因为它不支持泛型接口协变-你不能将IEnumerable<Derived>视为IEnumerable<Base>
  2. 即使IEnumerable<T>是协变的,C# 4中也无法使用这种方式,因为值类型不支持协变,从int[](一个IEnumerable<int>)到IEnumerable<object>的转换不能成功。

哦...我以为它必须是IEnumerable<T>。如果这样可以,那么为什么IEnumerable<object>不行呢?等等...算了吧。因为它是IEnumerable<int>,这是非常不同的。我现在明白了。谢谢Ani! - mpen
IEnumerable<T> 实现了 IEnumerable,因此您始终可以进行“向下”转换。 - Pauli Østerø
1
@Pauli:是的,但我遇到的问题是 int[] 根本没有实现 IEnumerable<object> ... 只有 IEnumerable<int> 而已,这是不同的。但是仅使用 IEnumerable 就可以解决问题。 - mpen
你可能已经意识到了,IEnumerable<object>和IEnumerable并不相同,尽管它们的枚举器都返回object :) - Pauli Østerø
1
我甚至不知道他们在C#4中添加了那个!太酷了。我可能在不知情的情况下使用了几次:p 那些东西仍然有点让我困惑(协变/逆变)。 - mpen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接