14

Bartype から 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.Cast2 つの制約のないジェネリック型の実行時キャストを行うため、コンパイル時にどのキャスト演算子を使用するかを知ることができません。必要なことを行うには、次を使用できます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 に答える
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 に答える