2012-06-09 15 views
6

単一基本型から継承する2つの型を使用すると、条件演算子(?:)は機能しません。同じ基本型を継承する2つの型で条件付き演算子が動作しない

私が持っている例がある:長い形式が正常に動作します

ActionResult foo = (someCondition)? 
         RedirectToAction("Foo","Bar") : 
         Redirect(someUrl); 

ActionResult foo; 

if(someCondition) 
{ 
    foo = RedirectToAction("Foo","Bar"); 
} 
else 
{ 
    foo = Redirect(someUrl); 
} 

どちらの戻り値の型、RedirectToRouteResultRedirectResultActionResultから継承します。

+0

をすることができますaxact条件を表示しますか? –

+0

この場合は単なるboolです。 –

+0

基本タイプにキャストしよう:(例:ActionResult foo =(someCondition)? (ActionResult)RedirectToAction( "Foo"、 "Bar"): (ActionResult)リダイレクト(someUrl); ) –

答えて

11

単一基本型を継承する2つの型を使用すると、条件演算子(?:)は機能しません。

条件式のタイプは、言語仕様に従って、第二オペランド又は第三のオペランドのタイプのいずれかタイプでなければなりません。コンパイラーは、共通の基本タイプ、または両方のオペランドを変換できる別のタイプを見つけようとしません。 式のの使用は、その型がどのように決定されるかに影響しません。したがって、変数の代入はここでは無関係です。

については、なぜ言語がこのように定義されていますか?指定、実装、テスト、予測するのがかなり簡単です。これは言語デザインではかなり一般的です。言語を単純に保つことは、特定の状況ではやや厄介なものであっても、長期的にはより良い賭けです。

詳細については、C#4仕様のセクション7.14を参照してください。

実際にはが条件式を求めているタイプに第2または第3オペランドをキャスティングすると、問題を解決できます。これは、多くの場合で起動します別の状況がNULL可能なタイプであることに注意してください:

// Invalid 
int? a = SomeCondition ? null : 10; 

// All valid 
int? a = SomeCondition ? (int?) null : 10; 
int? b = SomeCondition ? default(int?) : 10; 
int? c = SomeCondition ? null : (int?) 10; 
+0

ありがとう@JonSkeetと追加の情​​報と解決策についても。 –

1

条件演算子がRedirectToRouteResultまたはRedirectResultのいずれかとすることができる、そのコンポーネントから結果のタイプを決定することはできません。これを解決するためには、明示的に基本型へのコンポーネントのいずれかにキャストする(あるいはその両方)必要があります。

ActionResult foo = (someCondition) ? 
        (ActionResult)RedirectToAction("Foo","Bar") : 
        Redirect(someUrl); 
1

条件部分は関係なく、それが割り当てられています変数の自分自身を解決しようとします。コンパイラは、条件付き部分に関する限り、RedirectToRouteResultはRedirectResultと同じにキャストできないため、戻り値として使用するクラスを判断できないという警告を出します。片側だけが基本クラスにキャストされた場合は、他のは、暗黙のうちにその最初が有効になり、鋳造、同様にキャストされます。

var foo = (someCondition)? 
        (ActionResult)RedirectToAction("Foo","Bar") : 
        Redirect(someUrl); 

だけあまりにも選択肢をキャスト:

var foo = (someCondition)? 
    RedirectToAction("Foo","Bar") : 
    (ActionResult)Redirect(someUrl);