2

最近、linq のCastメソッドと一緒にユーザー定義のキャスト (キャスト演算子のオーバーロード) を使用する際に問題が発生しました。

ここSOで私の問題について同様の質問を見つけました。また、それをよく説明するリンクも見つけました。私の問題は解決しました。

しかし、何か疑問に思っていました:

これが機能しない理由:

foolist.Cast<bar>(); // throws InvalidCastException

これが機能している間:

foolist.Select(f => (bar)f).ToList(); // works fine

それぞれのメソッドの実装に関係するものだと思います。もしそうなら、Cast メソッドにSelectと同様の実装を持たせて、ユーザー定義のキャストで使用できるようにすることはできませんでした (これはある程度予想されるためです)。

注: 失敗する理由を尋ねているわけではありません。Cast メソッドが失敗する方法で記述された理由を尋ねています。

4

1 に答える 1

0

その理由は、Castメソッドが一般的なコンテキストでキャストを実行するためです

IEnumerable<T> Cast<T>(this IEnumerable e) {
  foreach (object cur in e) { 
    return (T)cur;
  }
}

実際のキャストロジックは、この正確なポイントで検証および発行されます。この点はジェネリック関数にあり、T最終的にインスタンス化される型のユーザー定義の変換についての知識はありません。アクセスできるのは、標準のCLRスタイルの変換だけです。

2番目の例では、(ジェネリック型パラメーターではなく)実際の型でキャストを行っています。したがって、C#コンパイラは、そのオブジェクトのすべてのユーザー定義の変換にアクセスでき、最も適切な変換を挿入できます。

于 2013-03-04T21:02:35.490 に答える