Possible Duplicate:
IEnumerable.Cast<>可能的重复:IEnumerable.Cast < >
One can implicitly convert from int to double. Why does "Specified cast is not valid." exception is raised here?
可以隐式地将int转换为double。为什么“指定的强制类型转换无效”在这里引发异常?
double[] a = Enumerable.Range(0, 7).Cast<double>().ToArray();
I have tried several "versions" of it.
我试过几个“版本”。
P.S. I know possible solutions like:
附注:我知道可能的解决办法,比如:
double[] a = Enumerable.Range(0, 7).Select(x => (double)x).ToArray();
But I'm curious how Cast works => why it doesn't work in this example which looks so obvious.
但是我很好奇Cast是如何工作的=>为什么在这个看起来很明显的例子中它不工作。
2 个解决方案
#1
4
Cast
is made to turn an IEnumerable
(untyped) to an IEnumerable<T>
(generically typed). It won't actually differently-cast any of the members.
Cast被用来将IEnumerable(非类型化)转换为IEnumerable (T>)(泛型)。它不会有任何不同的成员。
Per this answer:
每一个答案:
Well, you have incorrect expectations of Cast, that's all - it's meant to deal with boxing/unboxing, reference and identity conversions, and that's all. It's unfortunate that the documentation isn't as clear as it might be
你对角色的期望是错误的,仅此而已——它是用来处理装箱/拆箱、引用和身份转换的,仅此而已。不幸的是,文档并不像它可能的那样清晰
So, you're stuck with .Select()
.
因此,您被困在了。select()中。
#2
4
The reason this fails is because essentially you're doing this:
失败的原因是因为你在做这个:
int x = 10;
object f = x;
double d = (double) f;
The int is getting boxed into the object, and when you go to unbox it, you're trying to unbox it to a double.
int被装入对象中,当你打开它时,你试图将它打开到double。
More specifically, here's the implementation of Cast:
更具体地说,这是Cast的实现:
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
{
IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
if (enumerable != null)
{
return enumerable;
}
if (source == null)
{
throw Error.ArgumentNull("source");
}
return Enumerable.CastIterator<TResult>(source);
}
private static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source)
{
foreach (object current in source)
{
yield return (TResult)current;
}
yield break;
}
As you can see, it's looping through the IEnumerable and boxing each element in the source. It then tries to unbox at which point you blow up.
如您所见,它通过IEnumerable接口进行循环,并对源代码中的每个元素进行装箱。然后它试着打开你爆炸的地方。
#1
4
Cast
is made to turn an IEnumerable
(untyped) to an IEnumerable<T>
(generically typed). It won't actually differently-cast any of the members.
Cast被用来将IEnumerable(非类型化)转换为IEnumerable (T>)(泛型)。它不会有任何不同的成员。
Per this answer:
每一个答案:
Well, you have incorrect expectations of Cast, that's all - it's meant to deal with boxing/unboxing, reference and identity conversions, and that's all. It's unfortunate that the documentation isn't as clear as it might be
你对角色的期望是错误的,仅此而已——它是用来处理装箱/拆箱、引用和身份转换的,仅此而已。不幸的是,文档并不像它可能的那样清晰
So, you're stuck with .Select()
.
因此,您被困在了。select()中。
#2
4
The reason this fails is because essentially you're doing this:
失败的原因是因为你在做这个:
int x = 10;
object f = x;
double d = (double) f;
The int is getting boxed into the object, and when you go to unbox it, you're trying to unbox it to a double.
int被装入对象中,当你打开它时,你试图将它打开到double。
More specifically, here's the implementation of Cast:
更具体地说,这是Cast的实现:
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
{
IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
if (enumerable != null)
{
return enumerable;
}
if (source == null)
{
throw Error.ArgumentNull("source");
}
return Enumerable.CastIterator<TResult>(source);
}
private static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source)
{
foreach (object current in source)
{
yield return (TResult)current;
}
yield break;
}
As you can see, it's looping through the IEnumerable and boxing each element in the source. It then tries to unbox at which point you blow up.
如您所见,它通过IEnumerable接口进行循环,并对源代码中的每个元素进行装箱。然后它试着打开你爆炸的地方。