为什么Enumerable.Cast不使用用户定义的强制转换?

时间:2012-09-17 07:49:39

标签: c# casting ienumerable

说,我们有两个班级:

public class A
{
    public int a;
}

public class B
{
    public int b;

    public static implicit operator B(A x)
    {
        return new B { b = x.a };
    }
}

然后为什么

A a = new A { a = 0 };
B b = a; //OK

List<A> listA = new List<A> { new A { a = 0 } };
List<B> listB = listA.Cast<B>().ToList(); //throws InvalidCastException

explicit运算符相同。

P.S。:手动(separetely)投射每个元素

List<B> listB = listA.Select<A, B>(s => s).ToList(); //OK

1 个答案:

答案 0 :(得分:10)

Enumerable.Cast的名称具有误导性,因为它的目的是取消装箱值。它适用于IEnumerable({{1>}上的)以生成IEnumerable<T>。如果您已经拥有IEnumerable<T> IEnumerable<T>,则很可能不是您要使用的方法。

从技术上讲,它正在做这样的事情:

Enumerable.Cast

如果foreach(object obj in value) yield return (T)obj; 不是盒装值,则会产生T

您可以自己测试此行为:

InvalidCastException

您有两种可能的解决方案:

  1. 使用int i = 0; object o = i; double d1 = (double)i; // Works. double d2 = (double)o; // Throws InvalidCastException
  2. 创建适用于Select(x => (B)x)而不是Cast的扩展方法IEnumerable<T>
相关问题