14

我定义了从 typeBar到 type的显式转换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<Foo>();

它抛出一个异常,说它不能转换。

我如何告诉Cast使用我的演员来尝试转换?

4

5 回答 5

11

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

manyFoos.Select(foo => (Bar)foo);
于 2013-09-23T06:49:19.040 回答
6

linqCast方法本质上是装箱和拆箱。它不知道 C# 中定义的隐式或显式转换运算符,编译器处理标准方法调用。

你必须做这样的事情:

var manyFoos = manyBars.Select(bar => (Foo)bar);
于 2013-09-23T06:46:53.453 回答
5

正如所有其他答案指出的类型在编译时是未知的,因为Cast方法不是generic。它持有类型 ofobject并显式转换为T. 这失败了,因为您没有转换运算符 from objectto Foo。这也是不可能的。

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

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

然后像这样使用它

 var result = bars.DynamicCast<Foo>();//this works
于 2013-09-23T07:30:43.530 回答
2

使用Select

var manyFoos = manyBars.Select(bar => (Foo)bar);
于 2013-09-23T06:46:27.493 回答
1

您的代码实际上并没有编译。我假设“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<Bar> bars = new List<Bar>();
            for (int i = 0; i < 10; i++)
                bars.Add(new Bar() { Gar = i.ToString() });

            var result = bars.Cast<Foo>();
        }

+

我鼓励您阅读有关协方差的内容。

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

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

您必须使用接口来做到这一点。

于 2013-09-23T06:46:30.417 回答