2011-03-30 131 views
31

在使用新概念時,我碰到Ternary Operator,它很美。玩了一段時間後,我決定測試它的極限。使用三元運算符的方法調用

但是,當我無法獲得某行代碼進行編譯時,我的樂趣很快就結束了。

int a = 5; 
int b = 10; 
a == b ? doThis() : doThat() 

    private void doThis() 
    { 
     MessageBox.Show("Did this"); 
    } 
    private void doThat() 
    { 
     MessageBox.Show("Did that"); 
    } 

這一行給了我兩個錯誤:

Error 1 Only assignment, call, increment, decrement, and new object expressions can be used as a statement 
Error 2 Type of conditional expression cannot be determined because there is no implicit conversion between 'void' and 'void' 

我從來沒有使用一個Ternary Operator決定調用哪個方法,我也不知道,如果它甚至有可能。我只是想方法調用一行If Else Statement的想法。

我已經做了一些研究,找不到任何人做這個事情的例子,所以我想我可能希望得到一些無法提供的東西。

如果這是可能的,請啓發我在我的錯誤行爲,這是不可能的,有沒有另一種方式?

+1

確保函數doThis和doThat返回int類型的值。 – Chandu 2011-03-30 17:52:30

+0

哎呀,讓我張貼我的方法真的很快。 – 2011-03-30 17:53:33

+1

如果你真的想要一個單行的'If Else',就把它寫成一行:'if(condition)doThis();否則doThat();'承認,三元運算符(如果它的工作方式你認爲)會更短,但簡潔並不總是一件好事。 – 2011-03-30 19:17:21

回答

2

爲什麼上面的語句不工作是由其他用戶提供的,有效地沒有原因回答我的真實問題。

在玩了更多之後,我發現你可以使用這個操作符來完成上面的語句,但是它會導致一些錯誤的代碼。

如果我要將上面的語句改爲;

int a = 5; 
int b = 10; 
int result = a == b ? doThis() : doThat(); 

private int doThis() 
{ 
    MessageBox.Show("Did this"); 
    return 0; 
} 
private int doThat() 
{ 
    MessageBox.Show("Did that"); 
    return 1; 
} 

此代碼將編譯和執行應該的方式。但是,如果這些方法本來不是要返回任何內容,並且引用了代碼中的其他區域,則您現在必須每次處理返回對象以調用這些方法。

否則,您現在可以使用三元運算符作爲單行方法選擇器,甚至可以知道使用結果在下一行調用哪種方法。

int result = a == b ? doThis() : doThat(); 

if (result == 0) 
    MessageBox.Show("You called doThis()!"); 

現在,這個代碼是絕對沒有意義的,可以由的if else很容易做到,但我只是想知道,如果它可以做,什麼你必須做的就是它的工作。

現在我知道你可以有效地返回這些方法中的任何類型,這可能會變得更有用。它可能被認爲是一種「錯誤的編碼實踐」,但可能在它從未想過的情況下變得非常有用。

您可以基於任何條件訪問一個對象或另一個對象,這可能在一行代碼中非常有用。

UserPrivileges result = user.Group == Group.Admin ? GiveAdminPrivileges() : GiveUserPrivileges(); 

private UserPrivileges GiveAdminPrivileges() 
{ 
     //Enter code here 
     return var; 
} 
private UserPrivileges GiveUserPrivileges() 
{ 
     //Enter code here 
     return var; 
} 

當然,這可以通過一個if語句來完成,但我覺得用三元運算符用於其他用途,使編程的樂趣。現在,這可能不如If Else聲明那麼有效,在這種情況下,我絕不會使用它。

+4

這樣做確實沒有意義。 – SLaks 2011-03-30 18:12:17

+0

同意,但爲了完整性,您還可以返回一個bool,字符串或任何對象。但是,真的,聲明1是什麼;真的意味着一個編譯器?沒有多少,它不能幫助學習良好編碼實踐的細微差別 – Michael 2011-03-30 18:14:12

+0

@邁克爾我不知道這一點,這就是我的問題。我想知道如何讓這個工作以及使用它的好處/後果。選擇返回類型的能力使其更加有用。 – 2011-03-30 18:15:58

15

三元運算符必須返回一些東西。一個典型的用法是這樣的:

int x = (a > b) ? a : b; 

如果你嘗試類似

a + b; 

編譯器會抱怨。

(a > b) ? a - b : b - a; 

基本上是爲任何一個快捷方式 「A - B」 或 「B - A」,這是不是在自己的合法聲明。

+5

+1。如果DoThis()和DoThat()返回了某些東西,那麼可以使用三元來控制執行並將結果賦給某個局部變量,但這不是三元運算符的意圖;其他開發人員會認爲返回值對你來說比副作用更重要。使用基本的if語句;你的意圖將保持清晰(你不必爲了聰明而混淆你的方法簽名)。 – KeithS 2011-03-30 18:02:23

+4

+1,另一個關鍵點是可以從三元運算符返回的兩個值必須是相同類型或可以隱式轉換爲相同類型。 – 2011-03-31 13:12:06

31

三元運算符用於返回值,這些值必須分配。假設方法doThis()doThat()返回值,一個簡單的分配將解決您的問題。

如果你想做你正在嘗試的,這是可能的,但解決方案並不漂亮。

int a = 5; 
int b = 10; 
(a == b ? (Action)doThis : doThat)(); 

這將返回一個Action委託,然後由括號調用。這不是實現這個目標的典型方法。

+1

的確,不是正確的做事方式;但絕對是對這個問題最正確的答案:OP想要使用三元運算符來選擇一個方法來調用,而這正是你的片段的功能;) – 2011-03-30 18:37:46

+0

爲什麼這不是「正確的」?另一張海報甚至稱之爲愚蠢。 – Morgoth 2014-10-31 01:35:12

+0

答案是它大幅度減慢http://www.dotnetperls.com/action – Morgoth 2014-10-31 01:35:47

1

條件運算符是一個返回值的表達式。
您不能將它用於返回void的函數。

而應該使用正常的if

+0

很好但是,OP可能假設用戶可以在條件運算符中使用一種C/C++風格的語法,其語法允許用戶在條件操作中調用方法。但是我認爲,從OP的說法來看,他們並沒有將它們的條件運算符用於C/C++語法。 – Jake 2014-01-11 19:04:25

1

因爲某種原因,.NET不支持(可讀版本)。它非常乾淨,使你的代碼難以閱讀。邏輯樹應該相對容易遍歷。如果我要走進一份工作,並且所有使用三元的代碼來分配值,調用方法等,我想我會走出去。

+0

你仍然需要一個任務。 – NerdFury 2011-03-30 18:04:07

+0

我認爲這會使代碼難以閱讀的唯一方法是如果你使用了非描述性變量名和幻數(似乎沒有意義的數字)。如果三元操作符正確使用,它應該像If/Else一樣簡單。 – 2011-03-30 18:30:41

+0

方法名稱可能很長並且經常涉及參數。我不想讀取一個200字符的行來判斷一個方法調用的開始和另一個結束。多行(至少對我來說)通常更容易閱讀,幾乎不需要多行代碼。比較:'(VicePresidentsAttendee.AnnualSalary == MoneyHelper.MonetizeInt(SalaryThreshold))? RaiseHelper.AddABillionDollarBonus(VicePresidentAttendee.PersonId):RaiseHelper.RegisterPersonForYearlyRaise(SalaryThreshold,PersonId,SickDaysLastQuarter,TypingSpeedInGoalWordsPerMinute,LunarPhaseOnLastPiDay);' – FreeAsInBeer 2011-03-30 18:47:35

2

你應該能夠做到這一點,雖然:

 int a = 5; 
     int b = 10; 

     var func = a == b ? (Action)doThis : (Action)doThat; // decide which method 

     func(); // call it 

不,這是非常有用的

7

如果你真的想調用的條件運算void方法,你可以使用委託:

(something ? new Action(DoThis) : DoThat)(); 

如果方法帶參數,這將變得更加複雜。
您可以將lambda表達式置於條件中或使用Action<T>

但是,這是一個非常愚蠢的事情。