IEnumerable 。即使定义了一个显式的强制转换操作符,它也不会工作?

我有一个显式转换,从类型Bar定义到类型Foo

 public class Bar { public static explicit operator Foo(Bar bar) { return new Foo(bar.Gar); } } public class Foo { public string Gar { get; set; } public Foo() { } public Foo(string gar) { Gar = gar; } } 

但是,当我这样做时:

 using System.Linq; ... var manyFoos = manyBars.Cast(); 

它抛出一个exception,说它无法施放。

如何告诉Cast使用我的Cast转换运算符来尝试转换?

Cast操作符是编译器在代码中使用强制转换时调用的静态方法。 它们不能动态使用。 Enumerable.Cast执行两个无约束generics类型的运行时转换,因此在编译期间无法知道哪些转换器要使用。 要做你想做的事,你可以使用Select

 manyFoos.Select(foo => (Bar)foo); 

linq Cast方法基本上是一个box和unbox。 它不知道C#中定义的隐式或显式转换运算符,编译器会处理标准方法调用。

你必须做这样的事情:

 var manyFoos = manyBars.Select(bar => (Foo)bar); 

由于Cast方法不是generic在编译时不知道所有其他答案指向类型。 它包含object类型并对T进行显式转换。 这会失败,因为您没有从objectFoo转换运算符。 这也是不可能的。

这是一个使用动态的工作,其中演员将在运行时完成。

 public static class DynamicEnumerable { public static IEnumerable DynamicCast(this IEnumerable source) { foreach (dynamic current in source) { yield return (T)(current); } } } 

然后就像使用它一样

  var result = bars.DynamicCast();//this works 

使用Select

 var manyFoos = manyBars.Select(bar => (Foo)bar); 

您的代码实际上没有编译。 我假设“Bar”类中还有一个属性“Gar”?

 public class Bar { public string Gar { get; set; } public static explicit operator Foo(Bar bar) { return new Foo(bar.Gar); } } public class Foo { public string Gar { get; set; } public Foo() { } public Foo(string gar) { Gar = gar; } } static void Main(string[] args) { List bars = new List(); for (int i = 0; i < 10; i++) bars.Add(new Bar() { Gar = i.ToString() }); var result = bars.Cast(); } 

+

我告诉你关于协方差的解读。

假设A可转换为B,如果X可转换为X ,则X是协变的。

使用C#的协方差(和逆变)概念,“可转换”意味着可通过隐式引用转换进行转换 – 例如A子类化B或A实现B.不包括数字转换,装箱转换和自定义转换。

你必须使用接口。