c# - 为什么 Enumerable.Cast 不使用用户定义的转换?

标签 c# casting ienumerable

比如说,我们有 2 个类:

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.:手动(单独)转换每个元素是可行的

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

最佳答案

Enumerable.Cast的名称具有误导性,因为它的目的是拆箱值。它适用于 IEnumerable (IEnumerable<T> 上)生成一个 IEnumerable<T> .如果您已经有 IEnumerable<T> Enumerable.Cast很可能不是您想要使用的方法。

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

foreach(object obj in value)
    yield return (T)obj;

如果T不是盒装值,这将导致 InvalidCastException .

你可以自己测试这个行为:

int i = 0;
object o = i;
double d1 = (double)i; // Works.
double d2 = (double)o; // Throws InvalidCastException

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

  1. 使用Select(x => (B)x)
  2. 创建一个扩展方法 Cast适用于 IEnumerable<T>而不是 IEnumerable .

关于c# - 为什么 Enumerable.Cast 不使用用户定义的转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12455076/

相关文章:

C#,如何在读取 Ace.OleDB 时更改数据类型

c# - Windows Phone 8 中的设备方向

c# - 在一组短字符串中查找非常常见的子字符串的算法

c# - 在 C# 中使用 "is"后跟 "as"而不是 "as"后跟 null 检查有什么意义?

controls - mvc显示模板中当前项目的索引

C# tostring(基数)

java - 在 Java 中为具有类型参数的类编写平等契约

java - Java 中对象的动态类型转换

c# - IEnumerable<T> 作为返回值,延迟执行和 N 层应用程序

c# - 我可以在运行时为 OrderBy 实例化一个 IComparer 类,而不考虑类型吗?