The conditional statement does not work with two types that inherit the same base type

Why does the conditional operator ( ?: Not work when used with two types that inherit from the same base type?

An example that I have:

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

Where the long form works fine:

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

Both return types, RedirectToRouteResult and RedirectResult , inherit from ActionResult .

+6
source share
3 answers

Why does the conditional operator (? :) not work when used with two types that inherit from the same base type?

The conditional expression type must be either the type of the second operand or the type of the third operand according to the language specification. The compiler does not try to find a common base type or another type to which both operands can be converted. Using an expression does not affect how its type is determined, so the purpose of the variables does not matter here.

As for why the language is defined as follows - it greatly simplifies the definition, implementation, testing and forecasting. This is quite common in language design — maintaining a simple language is generally the best option in the long run, even if it makes it somewhat more inconvenient in some specific situations.

See section 7.14 of the C # 4 specification for more details.

Casting the second or third operand to the type you really want for the conditional expression is a way to fix the problem. Note that another situation that often arises is types with a null value:

 // 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; 
+11
source

A conditional statement cannot determine the resulting type from its components, which can be either RedirectToRouteResult or RedirectResult . To resolve this, you must explicitly point either (or both) components to the base type:

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

The conditional part is trying to independently solve, regardless of the variable to which it is assigned. The compiler gives a warning that it cannot determine which class to use as the return value, since RedirectToRouteResult cannot be the same as RedirectResult with respect to the conditional part. However, if only one side is passed to the base class, the other is also implicitly activated, so the execution of the first will be valid:

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

but only an alternative:

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

Source: https://habr.com/ru/post/917698/


All Articles