【发布时间】:2021-07-24 03:53:29
【问题描述】:
TL;DR - 我希望这些都可以正常工作,但是(每个 cmets)它们不会:
var c1 = new[] { FileMode.Append }.Cast<int>();
var c2 = new[] { FileMode.Append }.Select(x => (int)x);
var c3 = new[] { FileMode.Append }.Select(x => x).Cast<int>();
foreach (var x in c1 as IEnumerable)
Console.WriteLine(x); // Append (I would expect 6 here!)
foreach (var x in c2 as IEnumerable)
Console.WriteLine(x); // 6
foreach (var x in c3 as IEnumerable)
Console.WriteLine(x); // 6
这是一个人为的例子;如果我没有必要,我显然不会将集合转换为IEnumerable,在这种情况下,一切都会按预期工作。但我正在开发一个库,其中包含几种方法,这些方法采用object 并返回序列化的字符串表示形式。如果它通过反射确定该对象实现了IEnumerable,它将枚举它,并且在几乎所有情况下都返回预期的结果……除了Array.Cast<T> 这个奇怪的情况。
我可以在这里做两件事:
- 告诉用户首先实现
IEnumerables,例如ToList()。 - 为每个采用
IEnumerable<T>的受影响方法创建一个重载。
出于不同的原因,这些都不是理想的。当Array.Cast<T>() 被传递时,一个采用object 的方法是否有可能以某种方式推断T?
【问题讨论】:
-
查看this answer 以了解
IEnumerable.Cast<T>的来源。在这个特定的用例中,Cast<T>只是返回原来的数组 - 类型为FileMode而不是类型为int。 (它实际上并没有强制转换任何东西,因为这个特定的枚举是作为 int 实现的。) -
如果您处理的是
IEnumerable,那么您需要使用foreach(int x in whatever)来获得所需的演员表。
标签: c# linq reflection