2011-08-16 7 views
8

Action<T>の値を設定するときに、私はこの条件付きステートメントでこの奇妙な問題を抱えています。それは正常なifを使用して解決するのがかなり簡単なので、私はこれを回避する方法を知らないわけではありません。条件文、ジェネリックデリゲート不要キャスト

public class Test 
{ 
    public bool Foo { get; set; } 
    public Action<bool> Action { get; set; } 

    public void A() 
    { 
     Action = Foo ? B : C;//Gives compiler error 
    } 

    public void B(bool value) 
    { 

    } 

    public void C(bool value) 
    { 

    } 
} 

これはメッセージ

「メソッドグループ」と「メソッドグループ」の間の暗黙的な変換はありませんと私にコンパイルエラーを与える:

は、ここに私の問題です。

なぜこれが違法であるかわかりませんが、これは奇妙です。

ちなみに、以下の構文は、(ビューのコンパイラポイントから)これが有効になります。

public void A() 
    { 
     Action = Foo ? (Action<bool>) B : C; 
    } 

なぜキャストが必要である、ように多分あなたは質問を読むことができますか?

答えて

2

あなたは2つの同様の概念を融合させています。

A)メソッドグループ。メソッドグループは、同じ名前の1つ以上のC#メソッドです。これは主にコンパイラによって使用される抽象化です。メソッドグループを渡すことはできません。メソッドグループを使って行うことができるのは、それを呼び出すこと、またはその中からデリゲートを作成することだけです。型シグネチャが一致する場合は、メソッドグループから暗黙的にデリゲートを作成できます。

B)代理人。あなたは、代議員が何であるかを知っています。特定の型シグネチャを持ち、メソッドを直接参照します。それを呼び出すだけでなく、それを渡してファーストクラスのオブジェクトとして扱うことができます。

したがって、最初の例では、一方の側のメソッドグループBともう一方の側の別のメソッドグループCが返されます。三項演算子は、同じ型を両側に返す必要がありますが、どちらの側にキャストするかはわかりません。結果を(Action<bool>)に割り当てた変数タイプは、式の型を決定しません。だからあいまいです。

2番目の例では、メソッドグループBを、3者演算子の一方の側のAction<bool>代理人に合法的にキャストします。式の曖昧さを解消しようとする過程で、コンパイラは各辺を他の辺の型にキャストしようとします。メソッドグループCAction<bool>に正常にキャストすることができます。そのようにして、式は合法です。

-1

アクションは特定のデリゲートクラスであり、同様のシグネチャを持つ通常のデリゲートとの間で利用可能な暗黙の変換はありません。

+0

私はC#コンパイラがそれをチェックするほどスマートだと思った... –

1

BCは実際には代理人ではないためです。それらはメソッドグループであり、暗黙のうちにデリゲート(特にAction<bool>)に変換できますが、それは同じことではありません。

BCは現在(型付けされていない)メソッドグループであるため、コンパイラはその型を決定することができません。それがあなたに伝えられるように、それらの間に暗黙の変換はありません。

は同様に、それは (あるいは少なくとも はしません)代入演算子の反対側に目を通すことができないと、「ああ、それは Action<bool>でなければなりません」と言います。

あなたはキャストを追加すると、左の分岐式の型がAction<bool>になり、そこ反対側のメソッド群との間の暗黙的な変換とその代理人であるので、コンパイラが再び幸せです:の種類式全体はAction<bool>です。

0
私が思う

Eric will again tell me, that my reasoning is slightly incorrectが、私はそれをとにかく試してみて、メソッドグループ

:-)彼の補正のための希望を与える、たとえばBのために、種類を持っていない、それはオブジェクトではありません(B.GetType()はコンパイルされません)。
これは簡単に型に変換できるため、暗黙のキャストが存在します。 サンプル:リンクされた質問に見ることができるよう

Action<bool> a = B; // implicit cast taking place. 

はしかし、三元式が表現マッチの両方の部分戻り値の型を見つけようとします。後でAction<bool>に変換する必要があることはわかりません。メソッドグループはそれ自体の型ではないので、それらの間の変換はありません。BCに変換できません。そのため、コンパイラはそれについて不平を言います。

Action<bool>に3進表現の部分をキャストすると、戻り値の型はその型でなければならず、3進表現の他の部分がその型への暗黙のキャストをサポートしているかどうかがチェックされます。これが当てはまるので、コードはコンパイルされます。