Conditional operator doesn't work with two types that inherit the same base type

后端 未结 3 1739
遇见更好的自我
遇见更好的自我 2021-01-11 14:52

How come the conditional operator (?:) doesn\'t work when used with two types that inherit from a single base type?

The example I have is:



        
相关标签:
3条回答
  • 2021-01-11 15:32

    The conditional operator cannot determine the resultant type from its components, which may be either RedirectToRouteResult or RedirectResult. In order to resolve this, you should explicitly cast either (or both) of the components to the base type:

    ActionResult foo = (someCondition) ? 
                       (ActionResult)RedirectToAction("Foo","Bar") :
                       Redirect(someUrl);
    
    0 讨论(0)
  • 2021-01-11 15:36

    How come the conditional operator (?:) doesn't work when used with two types that inherit from a single base type?

    The type of the conditional expression has to be either the type of the second operand or the type of the third operand, as per the language specification. The compiler doesn't try to find a common base type, or another type that both operands can be converted to. The use of the expression doesn't affect how its type is determined - so the variable assignment is irrelevant here.

    As for why the language is defined like this - it makes it considerably simpler to specify, implement, test and predict. This is fairly common in language design - keeping the language simple is usually a better bet in the long run, even if it makes it slightly more awkward in some specific situations.

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

    Casting either the second or third operand to the type that you actually want for the conditional expression is the way to fix the problem. Note that another situation this often comes up in is nullable types:

    // 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 讨论(0)
  • 2021-01-11 15:38

    The conditional part tries to resolve itself regardless of the variable it's being assigned to. The compiler gives a warning that it can't determine which class to use as a return value, because RedirectToRouteResult can't be cast the same as RedirectResult, as far as the conditional part is concerned. However if just one side is cast to the base class, the other is implicitly cast as well, so casting the first would be valid:

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

    but only casting the alternative too:

     var foo = (someCondition)? 
        RedirectToAction("Foo","Bar") :
       (ActionResult)Redirect(someUrl);
    
    0 讨论(0)
提交回复
热议问题