3

次のコードを入力しました。

Expression<Func<ContentItem, bool>> expression = 
                fileTypeGroupID.HasValue ? n => n.Document.MimeType.FileTypeGroupID == fileTypeGroupID.Value : n => true;

Visual Studioは、のタイプを推測できないと言っていますn

コードは私には問題ないように思えます。三項演算子を使用して、2つのExpressionリテラルのうちの1つをExpression変数に割り当てているだけです。

Visual Studioはn、三項演算子の内部のタイプを推測するのに十分なほど賢くないのでしょうか、それとも私が何らかの間違いを犯したのでしょうか。

4

3 に答える 3

13

この質問は、ほぼ毎日何らかの形で尋ねられます。

条件付き演算子タイプの分析は、外側から内側ではなく、内側から外側に進みます。条件演算子は、結果がどのタイプに割り当てられているかを知らないため、結果とそれらのタイプの代替を強制します。それは反対のことをします。結果と代替のタイプを計算し、これら2つのタイプのより一般的なものを取得してから、一般的なタイプが割り当てられる可能性があることを確認します。

結果と代替には、ラムダのタイプがどうあるべきかについての情報が含まれていないため、条件のタイプを推測することはできません。したがって、割り当てが正しいことを確認できません。

言語がそのように設計された理由を考えることは啓発的です。オーバーロードがあるとします。

 void M(Func<string, int> f) {}
 void M(Func<double, double> f) {}

と電話

M( b ? n=>n.Foo() : n => n.Bar() );

タイプが外部から内部に推測される世界で、過負荷解決がMのどの過負荷が選択されるかをどのように決定するかを説明します。

今これを考えてみましょう:

M( b1 ? (b2 ? n=>n.Foo() : n => n.Bar() ) : (b3 ? n=>n.Blah() : n=>n.Abc()) );

難しくなりませんか?ここで、Foo、Bar、Blah、およびAbc自体が関数を使用するメソッドであり、ラムダを含む条件演算子を使用した引数があることを想像してみてください。

対応する大き​​な利点がなければ、型推論プロセスをそれほど複雑にしたくはありません。また、条件演算子にはそのような大きな利点はありません。

あなたの場合にあなたがすべきことは、結果と特定のタイプの代替の一方または両方をキャストすることです。

于 2011-12-14T15:10:29.523 に答える
2

これは、コンパイラが型を推測できなかった理由についての質問には答えませんが、簡単な回避策は、次のように式を記述することです。

Expression<Func<ContentItem, bool>> expression = 
  n => !fileTypeGroupID.HasValue || n.Document.MimeType.FileTypeGroupID == fileTypeGroupID.Value;
于 2011-12-14T15:19:09.250 に答える
1
fileTypeGroupID.HasValue ? (ContentItem n) => n.Document.MimeType.FileTypeGroupID == fileTypeGroupID.Value
                         : (ContentItem n) => true;

条件演算子はの正しい名前であることに注意してください。? :これは三項演算子の例です(多くのプログラミング言語で唯一の三項演算子です)。

于 2011-12-14T15:07:28.897 に答える