【发布时间】:2012-06-14 18:48:05
【问题描述】:
考虑这个人为的、琐碎的例子:
var foo = new byte[] {246, 127};
var bar = foo.Cast<sbyte>();
var baz = new List<sbyte>();
foreach (var sb in bar)
{
baz.Add(sb);
}
foreach (var sb in baz)
{
Console.WriteLine(sb);
}
借助二进制补码的魔力,-10 和 127 会打印到控制台。到现在为止还挺好。目光敏锐的人会看到我正在迭代一个可枚举并将其添加到列表中。这听起来像ToList:
var foo = new byte[] {246, 127};
var bar = foo.Cast<sbyte>();
var baz = bar.ToList();
//Nothing to see here
foreach (var sb in baz)
{
Console.WriteLine(sb);
}
除非那不起作用。我得到了这个例外:
异常类型:System.ArrayTypeMismatchException
消息:源数组类型无法分配给目标数组类型。
我觉得这个异常很奇怪,因为
-
ArrayTypeMismatchException- 我自己没有对数组做任何事情。这似乎是一个内部异常。 -
Cast<sbyte>工作正常(如第一个示例中所示),当使用ToArray或ToList时,问题就出现了。
我的目标是 .NET v4 x86,但在 3.5 中也是如此。
我不需要任何关于如何解决问题的建议,我已经设法做到了。我想知道的是为什么会发生这种行为?
编辑:
更奇怪的是,添加无意义的 select 语句会导致 ToList 正常工作:
var baz = bar.Select(x => x).ToList();
【问题讨论】:
-
使用
Select会产生{ -10, 127 }。这里有一个选角问题。肯定是有趣的错误消息。 -
@Lieven 是的,我收集了这么多,为什么
Select(x => x)在ToList之前更正它?这是一个毫无意义的投射,因为同样的东西被投射回来。 -
我有一个解释......只是需要一点时间才能写出来。好问题。
-
@vcsjones:因为这样很可能不再使用数组助手 - 使用
Select您将投影到IEnumerable -
+1 好问题。我喜欢涉及有趣边缘案例的问题。