1
public class Foo : IFooBarable {...}
public class Bar : IFooBarable {...}

では、なぜこれはコンパイルされないのでしょうか...

int a = 1;
IFooBarable ting = a == 1 ? new Foo() : new Bar();

しかし、これは...

IFooBarable ting = a == 1 ? new Foo() : new Foo();
IFooBarable ting = a == 1 ? new Bar() : new Bar();
4

4 に答える 4

7

コンパイラは最初に右側の式を評価しようとします。

? new Foo() : new Bar();

これら2つの間に暗黙的な変換がないため、エラーメッセージが表示されます。あなたはこれを行うことができます:

IFooBarable ting = a == 1 ? (IFooBarable)(new Foo()) : (IFooBarable)(new Bar());
于 2010-01-20T17:01:29.880 に答える
5

これは、C# 言語仕様のセクション 7.13 で説明されています。基本的に、このシナリオを無効にしているのは、3 項オペランドの 2 つの値の型間で暗黙的な変換が必要なことです。この変換は、変数の型がない場合に考慮されます。

したがって、Foo変換可能である必要がありBar、その逆もあります。どちらもそうではありませんので、コンパイルエラーが発生します。

ただし、後者の 2 つは 1 つのタイプ ( または のいずれFooBar) のみを考慮するため、機能します。それらは同じタイプであるため、式のタイプを決定するのは簡単で、うまく機能します。

于 2010-01-20T17:01:37.130 に答える
4

ここに投稿された正解に少し追加すると、この仕様につながる設計ガイドラインが 2 つあります。

1つ目は、「内から外へ」と推論することです。あなたが言う時

double x = 2 + y;

最初に x の型、次に 2 の型、次に y の型、次に (2+y) の型を計算し、最後に x と (2+y) に互換性のある型があるかどうかを計算します。ただし、2、y、または 2+y の型を決定する際に、x の型は使用しません。

これが良いルールである理由は、多くの場合、「レシーバー」のタイプがまさに私たちが解決しようとしているものだからです。

void M(Foo f) {}
void M(Bar b) {}
...
M(x ? y : z);

ここで何をすべきですか?これが Foo に行くのか Bar に行くのかを決定するために、オーバーロードの解決を行うために、条件式のタイプを解決する必要があります。したがって、これがたとえば Foo に行くという事実を、条件式の型の分析に使用することはできません! それはニワトリが先か卵が先かの問題です。

このルールの例外はラムダ式で、コンテキストから型を取りますその機能を適切に動作させることは非常に複雑でした。興味があれば、ラムダ式と匿名メソッドに関する私のブログ シリーズを参照してください。

2 番目の要素は、型を「魔法のように」作成することは決してないということです。型を推測しなければならないものがたくさん与えられたとき、私たちは常に実際に目の前にある型を推測します。

あなたの例では、分析は次のようになります。

  • 結果のタイプを計算する
  • 代替の型を計算する
  • 結果と代替の両方に適合する最適な型を見つける
  • 条件式の型から、条件式を使用している物の型への変換があることを確認してください。

最初のポイントに沿って、外側から内側への推論は行いません。式の型を計算するために、変数の型を知っているという事実を使用しません。しかし、今興味深いのは、あなたが持っているときです

b ? new Cat() : new Dog()

「条件式の型は集合 {Cat, Dog} の中で最適な型です」と言います。「条件式の型は、Cat と Dog の両方に対応する最適な型」とは言いません。それは哺乳類ですが、私たちはそうしません。代わりに、「結果は実際に見たものでなければならない」と言い、これら2つの選択肢のうち、どちらも明確な勝者ではありません. あなたが言ったなら

b ? (Animal) (new Cat()) : new Dog()

次に、Animal と Dog のどちらかを選択します。Animal が明らかに勝者です。

さて、この型分析を行うとき、実際には C# 仕様を正しく実装していないことに注意してください! エラーの詳細については、私の記事を参照してください。

于 2010-01-20T19:24:46.790 に答える
1

条件式の型は、結果が適用される変数からではなく、常にその 2 つの部分から推測されるためです。この推論は、型が等しいか、一方が他方と参照互換性がある場合にのみ機能します。この場合、2 つの型のどちらも、もう一方の型と参照互換性がありません。

于 2010-01-20T17:02:39.733 に答える