5

'メソッドグループ'と 'メソッドグループ'の間の暗黙的な変換がないために決定されます。条件演算子と比較デリゲート

ただし、if-else d OESは、すべての問題を持っていない:

Comparison<KeyValuePair<int, string>> sortMethod; 
if (isSortByActualValue) 
    sortMethod = CompareByKey; 
else 
    sortMethod = CompareByValue; 

(上記の両方の割り当てでは、すべての良い)

を私は比較デリゲートキャストのであれば、条件演算子を行いますで

Comparison<KeyValuePair<int, string>> sortMethod; 
sortMethod = isSortByActualValue ? (Comparison<KeyValuePair<int, string>>) CompareByKey : CompareByValue; 

は、(すべての良いですキャストが真の部分だけであってもキャストされてもキャストされたときの代入)

+2

CompareByAcutalValueとCompareByDisplayValueはどのように定義されていますか? CompareByKeyとCompareByValueの定義のみを表示します。 –

+0

私の投稿のコードスニペットはわかりやすくするために編集されました。私は(メソッドの)名前を部分的にしか変更しなかったことに気付かなかった。 Thanks Eric、CompareByActualValueのすべての参照をCompareByKey(およびCompareByDisplayValueをCompareByValue)に更新しました。 – Arun

答えて

7

Thエラーメソッドは実際にすべてを示していますが、それは直感的ではありません。メソッドを呼び出さずにメソッド名を使用する場合は、メソッドグループを処理しています。メソッドがオーバーロードされる可能性があり、その名前がオーバーロードされたメソッドのいずれかを示す可能性があるためです。

ここで、メソッドグループは暗黙のうちに署名が一致するデリゲートに変換されるため、ifでの割り当てが機能するのはこのためです。

これまでのところ、とても良いです。ただし、条件演算子?:は、2番目と3番目の引数を暗黙的に変換できる共通の型を推論する必要があり、すべての変換を考慮しません(これにはさまざまな問題があります)。両方の引数の型が同じかどうか、またはどちらか一方が暗黙的に他方に変換可能かどうかを調べるだけです。

両方の引数はメソッドグループですが、実際には異なるメソッドグループであり、メソッドグループを別のものに変換することはできません。どちらも簡単にデリゲートに変換できますが、コンパイラはこの使用法を禁止しています。

同じことによって、他のタイプのために真である:

object = someBool ? "" : New List<Integer>(); 

も、同様の理由で、コンパイルに失敗します。そして再び、我々は明示的に共通の基本型の引数のいずれかをキャストすることによって、これはコンパイルすることができます:

object = someBool ? (object) "" : New List<Integer>(); 
+1

+1ですが、「第2引数と第3引数の型を推論する必要があります」を「第2引数と第3引数が暗黙的に変換できる共通の型を推測する必要があります」と変更します。 – phoog

+0

なぜisSortByActualValue ? CompareByKey:CompareByKey'コンパイル?彼らは同じ方法群ではありませんか? – svick

+0

@svickメソッドグループとは無関係に、メソッドグループからメソッドグループへの変換は存在しません。私はそれをより明確にしておくべきであり、普通のタイプにはこの変換がないので、かなり特殊なケースです。私はこれがC#の仕様にどのように正確に記述されているのかわかりません。 –

3

を、あなたのCompareByKeyのような表現を持っている場合、それは任意の特定の.NET型を持っていますが、持っていません特殊な "メソッドグループ"です。それはCompareByKeyと呼ばれるいくつかのメソッドを持つことができ、どちらが欲しいかは不明です(メソッドが1つしかない場合でもまったく同じです)。また、デリゲートタイプが何を求めているのかは不明です。 Comparison<KeyValuePair<int, string>>またはFunc<KeyValuePair<int, string>, int>です。

方法グループで何ができますか?それらを使用して明示的にデリゲート(new Comparison<KeyValuePair<int, string>>(CompareByKey))を作成できます。また、デリゲートを暗黙的に代理人に変換することもできます。これがあなたのifバージョンが機能する理由です。

これはあなたの問題と何が関係していますか?条件付き演算子を使用する場合、コンパイラは式全体の型を把握しなければならず、それを代入する変数の型を使用することはできません(C#では型推論の動作ではありません)。また、両方の式がメソッドグループであり、メソッドグループが互いに暗黙の変換なしで異なる型として扱われるため、式全体の型を判別することはできません。だから、あなたはエラーを取得します。

修正プログラムが見つかりました。条件付き演算子を使用しないか、キャスト(またはデリゲートコンストラクタ)を使用して明示的にオペランドの型を指定しないでください。