2013-04-20 136 views
4

當我將一個if-else改爲三元運算符作爲return語句時,我遇到了一個奇怪的行爲。三元運算符意外的行爲

我已經簡化這裏的代碼:

class Foo 
{ 
    private bool condition; 
    private int intValue = 1; 
    private decimal decimalValue = 1M; 

    public object TernaryGet 
    { 
     get 
     { 
      return condition ? decimalValue : intValue; 
     } 
    } 

    public object IfElseGet 
    { 
     get 
     { 
      if (condition) 
       return decimalValue; 
      return intValue; 
     } 
    } 

    public Foo(bool condition) 
    { 
     this.condition = condition; 
    } 
} 

class Program 
    { 
     static void Main(string[] args) 
     { 
      var fooTrue = new Foo(true); 
      var fooFalse = new Foo(false); 

      Console.WriteLine("{0}, {1}", fooTrue.TernaryGet.GetType(), fooTrue.IfElseGet.GetType()); 
      Console.WriteLine("{0}, {1}", fooFalse.TernaryGet.GetType(), fooFalse.IfElseGet.GetType()); 
     }   
    } 

從這個輸出是:

System.Decimal, System.Decimal 
System.Decimal, System.Int32 

我期望在第二行輸出的Int32兩個干將,但對於三元我得到了int的錯誤CLR類型。

不要介意代碼和它正在嘗試做什麼 - 我很好奇爲什麼會發生這種情況,所以如果任何人都可以解釋它,我會很感激。

回答

5

結果三元(有條件的)操作員始終是單一類型的 - 一個/兩個選項澆鑄到常見類型:

var result = condition ? decimalValue : intValue; 

result類型必須在編譯時靜態是已知的。因爲從intdecimal投的比decimal類型被選作整個? :運算符的類型。

所以你整個函數可以寫成(顯示自動強制轉換):

public object TurnaryGet 
{ 
    get 
    { 
     /*decimal*/ var result = condition ? decimalValue : (decimal)intValue; 
     return (object)result; 
    } 
} 
+0

好的答案,謝謝。 ReSharper建議改變爲三元論,就像我一樣沒頭腦,我隨它去了。儘管如此,這在邊緣案例上有點不足。我想要正確的CLR類型的原因是在MVC視圖中將它與編輯器模板一起用於各自的類型 – 2013-04-20 05:52:39

2
condition ? decimalValue : intValue; 

意味着

condition ? decimalValue : (decimal) intValue; 

嘗試,如果這項工作:(我很陌生,C#,但這項工作在Java)

condition ? (object) decimalValue : (object) intValue;