2010-08-24 32 views
4

看來編譯器不會讓這個語法飛了。內聯條件C# - 次最佳解決方案?

void main() 
{ 
    foo(false?0:""); 
} 

void foo(int i) {return;} 
void foo(string s) {return;} 

唯一的其他辦法,我可以看到這個固定的東西如下:

void bar(object o) 
{ 
if (o is string){//do this} 
else{//im an int, do this} 
} 

任何人有任何更好的想法?

+0

第一個選項是最好的。編譯器會爲你做檢查,不需要做一個需要一個對象的方法......還有一些額外的代碼,不需要任何東西 – Stefanvds 2010-08-24 14:36:25

回答

2

你是個例子,並沒有形成很多意義(第二個例子與第一個例子無關)。

我認爲第一個例子是細如:

void main() 
{ 
    foo(""); 
} 

由於0永遠不會被傳遞反正(假的永遠是假的),你不能沒有分配使用內聯有條件的地方運營商(其中你的例子缺乏)。

對於第二種方式,這可能是我多麼希望看到它:

void bar(object o) 
{ 
    if(o is string) foo(o as string); 
    else foo((int)o); 
} 
+0

爲什麼你不簡單地將Bar和string放進去? – 2010-08-24 14:28:15

+0

@Rune FS - Foo被重載,但由於o是Object類型,因此如果不將o轉換爲更具體的類型,就無法確定正確的重載。邏輯測試適當的演員。 – 2010-08-24 14:29:43

+0

@Justin:我瘋了嗎?每個人似乎都在提出類似你最後的建議,但我相信這是非法的! 'foo'什麼都不返回,所以它不能在三元表達式中使用 - 我錯了嗎? – 2010-08-24 14:32:57

1

我不會在一個對象作爲參數傳遞。整數將被裝箱,效率稍差。讓編譯器找出調用哪個方法。

如果你寫道:

foo(0); 
foo(""); 

適當的方法將被調用。你也可以寫:

if (condition) { 
    foo(0); 
} else { 
    foo(""); 
} 

取決於你想要做什麼(你的例子是缺乏一點細節)。

2

方法調用foo在編譯時確定,所以它不能根據條件評估的結果調用不同的方法(或過載)。相反,嘗試這樣的事:

condition ? foo(0) : foo("") 

這樣,編譯器會在執行重載解析成功,將解析爲foo(int)第一個呼叫,以foo(string)第二個呼叫。

編輯:正如其他指出的,你不能使用?:運算符作爲語句,也不能使用返回void的方法。如果您的實際方法返回兼容的類型,你可以這樣做:

int result = condition ? foo(0) : foo(""); 

如果沒有,你必須使用一個if

if (condition) 
    foo(0); 
else 
    foo(""); 
+0

好吧,但是你不能在C#中的一行上使用三元表達式...所以這是一種誤導。 – 2010-08-24 14:31:19

+1

-1您無法使用條件表達式本身沒有賦值。 – 2010-08-24 14:32:10

+0

如果這樣做會很好,但我不得不這樣做:var x = condition? foo(0):foo(「」);並讓foo()返回一些東西。 – maxp 2010-08-24 14:34:24

0

此:

foo(false?0:"") 

可能是這樣的:

false ? foo(0) : foo("") 
+1

-1你和Allon Guralnek有同樣的錯誤。沒有某種分配就不能使用條件運算符。這不會自行編譯。 – 2010-08-24 14:32:53

+0

我認爲它是一個表達式,在這種情況下,只要'foo'不是'void',它就是非常有效的。 – 2010-08-24 15:52:24

3

以這種方式,您不能在三元表達式中使用返回類型爲void的方法。故事結局。

要明白這是爲什麼,還記得那些三元運營商實際上確實 - 它評估以下幾點:

(condition ? [true value] : [false value]) 

它所意味的是,下面的代碼:

int x = a ? b : c; 

必須重寫爲

int x; 
if (a) 
{ 
    x = b; 
} 
else 
{ 
    x = c; 
} 

以上兩者在邏輯上是相同的。

那麼如何使用void作爲其返回類型的方法工作?

// Does this make sense? 
int x = condition ? foo(s) : foo(i); 

// Or this? 
if (condition) 
{ 
    x = foo(s); 
} 
else 
{ 
    x = foo(i); 
} 

顯然,上述內容不合法。

也就是說,如果只有您的foo重載返回值,其他人的建議將會有效。

換句話說,如果你的簽名是這樣的:

object foo(string s); 
object foo(int i); 

然後你可以這個(你把自己的返回值,但至少它會編譯):

object o = condition ? foo(0) : foo(""); 

無論如何,ol'if/else是你最好的選擇,在這種情況下。

0

條件運算符的兩個結果必須具有相同類型(或可隱式轉換)。所以foo(false ? 0 : "")將不起作用,因爲它試圖返回Int32StringHere關於條件運算符的更多信息。

我要做的修復是將該行更改爲false ? foo(0) : foo("")

編輯:德皮,不能像在那樣使用條件運算符。他們只能用於作業。你將不得不使用一個if/else塊。不是一條線,但它會在一個捏。

+0

這個修正已經在這個線程上被提出了幾次,但是必須返回一些東西,因此它不會編譯:) – maxp 2010-08-24 14:38:21

+0

記得我點擊閃亮的'post'按鈕後:D – comradecow 2010-08-24 14:40:05

1

條件運算符需要true和false部分是相同類型的。這是它不編譯的原因。

var x = condition ? 0 : ""; 

編譯器爲x選擇什麼類型?如果你真的希望它選擇對象進行強制轉換,或者你可以強制它選擇動態,在這種情況下,方法超載仍然可以工作,但是你的類型安全性很差。然而兩者都有強烈的氣味。 不得不測試運行時類型通常是一個設計錯誤,但是有限的代碼(總是會有相同的結果)很難用不同的方法來幫助測試運行時類型

1

如果使用Inline if C#中的表達式,「:」之前和之後的部分必須是相同的類型。你打算什麼都不會工作。

即使你喜歡做這樣的事情:

DateTime? theTime = true ? DateTime.Now : null; 

編譯器不滿意。在這種情況下,您將必須使用:

DateTime? theTime = true ? DateTime.Now : default(DateTime?);