2012-05-14 59 views
1

爲什麼編譯器無法自動轉換此表達式中的值?C#三態表達式類型轉換

var input = "Hello"; 
object x = string.IsNullOrEmpty(input) ? input : DBNull.Value; 

//could try this too and get similar compile time error 
object x2 = string.IsNullOrEmpty(input) ? 1 : input; 

我知道DBNull.Value不能轉換爲字符串;然而,我很好奇它爲什麼不能合併成一個對象,因爲結果只是存儲一個引用。如果您將(object)放在DBNull.Value的前面,它會編譯並運行得很好。

+0

答案的全部,除了gdoron的是缺少了這一點。這不是一個「嘿幫我做這個編譯」的問題。它更要問的是,爲什麼C#編譯器不能或者不能查看被分配的變量的類型與第二個和第三個參數中變量的類型。 –

+0

找到一個稍微不相關的問題這個答案http://stackoverflow.com/a/2215959/186359我認爲它基本上證明,您不能添加信息(賦值變量的類型)時評估表達式。我認爲這可能是真正的答案 –

回答

2

與修復:

string x = string.IsNullOrEmpty(input) ? 
             input : 
             DBNull.Value.ToString(); 

我發現這個極好的說明中埃裏克利珀blog

規格以下的?:操作狀態:

第二個和第三個操作數的?:操作符控制 的條件表達式的類型。設X和Y是第二個和第三個操作數的類型。然後,

  • 如果X和Y是相同的類型,則這是該條件 表達式的類型。否則,如果存在從X到Y, 而不是從Y到X的隱式轉換,則Y是條件表達式的類型。否則,如果存在從Y到X的隱式轉換,但不是從 X到Y,則X是條件表達式的類型。

  • 否則, 不能確定表達式類型,併發生編譯時錯誤。

在這種情況下:

  • stringDBNull是不是同一類型。
  • string沒有隱式轉換到DBNull
  • DBNull沒有隱式轉換到string

因此,我們結束了一個編譯時錯誤。

編譯器不檢查可以「容納」這兩種類型的類型。

+1

這很有道理。我想我正在尋找的是「隱含的」部分。有點讓你想知道爲什麼它不會嘗試隱式轉換爲它們分配的變量的類型。如果我存儲對象,我不在乎實際類型是什麼,因爲我只是存儲對它的引用。 –

+0

@MattPhillips。然後你發現它...... :) – gdoron

3

這是因爲string不能澆鑄到DbNull,反之亦然。使用三元運算符時,兩個結果操作數必須兼容。

+0

我將它與_「需要隱式從一種類型轉換爲另一種。」@ – gdoron

+0

@gdoron也沒有明確的轉換。 – Matthew

+0

我已經得到那部分。我想知道的是爲什麼編譯器不可能(可行)查看分配給(對象)的類型,並意識到這兩種類型都有一個隱式轉換爲對象。忘記他們彼此擁有什麼。 –

2

幫助編譯器找到自己想要的公共基類,像這樣:

object x = string.IsNullOrEmpty(input) ? (object)input : DBNull.Value;