2010-07-14 79 views
26

有另一種方式來寫是這樣的:C#。如果(a ==(b或c或d))。可能嗎?

if (a == x || a == y || a == z) 

的一種方式,我發現這樣做是這樣的:

if(new [] {x,y,z}.Contains(a)) 

有沒有其他的好辦法?

+2

爲什麼你想用其他方式?我只是好奇 – 2010-07-14 08:07:05

+0

@despart - 它對描述性變量名稱更有意義,但無論如何我仍然會使用邏輯運算符。 – ChaosPandion 2010-07-14 08:08:45

+0

可能是因爲創建一個數組來比較兩個以上的數字感覺不對。 – cHao 2010-07-14 08:08:51

回答

63

我經常使用的擴展方法模仿SQLS IN

public static bool IsIn<T>(this T obj, params T[] collection) { 
    return collection.Contains(obj); 
} 

這樣我可以做

if(a.IsIn(b, c, d)) { ... } 
+2

應該指出,這是做了完全相同的事情就像在你的第二個例子中一樣,但它會把它排列在一個數組中,並在它看不見的地方搜索它,這樣你就可以直接進行可讀的操作。 – 2010-07-14 08:12:31

+2

你一直太快了! (+1) – 2010-07-14 08:13:16

+0

@David Hedlund,我注意到,我只是在想,可能c#有這個東西 – Omu 2010-07-14 08:14:17

10

你有經典的switch語句:

switch(a) { 
    case x: 
    case y: 
    case z: 
     // Do stuff 
     break; 
} 
+0

同意;這是迄今爲止最好的方法(至少,這是我採取的方法)。 – 2010-07-14 08:17:03

+2

如果x,y和z不是常量,c#會嚇倒嗎? – cHao 2010-07-14 08:28:20

+0

@cHao,沒有,這將工作得很好!只要這些變量早些時候具有受影響的值,則將a與x,y和z的存儲值進行比較。 – SiN 2010-07-14 08:44:34

6

只是爲了樂趣:

using System; 

static class Program { 

    static bool In(this object obj, params object[] values) { 
     foreach (object value in values) { 
      if (obj.Equals(value)) { 
       return true; 
      } 
     } 
     return false; 
    } 

    static void Main(string[] args) { 
     bool test1 = 3.In(1, 2, 3); 
     bool test2 = 5.In(1, 2, 3); 
    } 
} 

但我真的覺得最好方式是寫普通支票

if(a == x || a == y || a == z) 

大家都能夠理解立即它做什麼。

+0

我也參加了這個解決方案(請參閱我的回答),儘管我強烈建議您製作該通用版,以避免裝箱/取消裝箱。調用仍然是完全一樣的,你不必顯式指定類型參數,因爲它將從使用中推斷出來...... – 2010-07-14 08:14:25

+0

@David Hedlund:好點! – 2010-07-14 08:18:47

+0

+1還沒有看到這種模式的代碼... :) – deostroll 2010-07-14 13:33:10

1
if(a==x?true:a==y?true:a==z?true:false) 
+1

ooooh有趣,但遠不如可讀(a == x || a == y || a == z)! – RYFN 2010-07-14 08:16:15

+7

我對如何投票非常矛盾。 – ChaosPandion 2010-07-14 08:16:54

3

所以,你要更換簡單,efficent語言結構,包含短路的優化到的東西要慢得多具有用於拋出異常的潛力?

但是,如果要比較的項目數量不固定,即在運行時它可能是t,u,v,w,x,y,z等等,那麼Collection。 Contains方法是唯一的選擇,但是你會傳遞集合對象而不是單個值,所以很少有內存分配問題。

如果您有大量項目比較'a',但項目在運行時不是動態的,那麼switch語句可能更適合。

+0

'HashSet '是我喜歡在處理動態數量比較時使用的。 – ChaosPandion 2010-07-14 08:20:03

2

爲什麼還需要另一種方式?由於這不是功能問題,我猜想重點是提高可讀性。 如果您有幾個有意義名稱的變量,那麼使用==進行比較將更具可讀性。如果你有更多,你可以使用Contains作爲你的其他樣本。 另一種方法是比較反對枚舉標誌:

[Flags] 
public enum Size 
{ 
    Small = 1, 
    Medium = 2, 
    Large = 4 
} 

然後找出是否mySizeSmallMedium

selectedSizes = Size.Small | Size.Medium; 
mySize = Size.Small; 
if (mySize & selectedSizes) 
{ 
    ... 
} 
1

試試這個

var res2 = new[] { 1, 2, 3 }.Any(x => x == 2); 
5

您的解決方案將其改寫爲

if(new [] {x,y,z}.Contains(a)) 

不是一個好的舉措。

您已經採取了一種簡單高效的邏輯運算方式,每個程序員都很容易理解,其中包含短路邏輯以加速運行,相反,您生成的代碼需要一些時間才能理解,哪些效率要低得多。

有時你的同事們會更喜歡它,如果你不想「聰明」!

+0

我確實認爲它會變慢,但「Contains」仍然會短路。那麼至少有任何合理的實施將是。 – 2010-07-14 13:09:53

+0

@Brian Gideon:'Contains'會短路,當然,如果已經找到一個匹配,但是在'Contains'開始之前它不會繼續比較,你需要初始化這個數組,並且它在這意味着你訪問'x','y'和'z'。如果'z'需要大量計算才能評估,並且'a == x',則在Contains操作甚至開始之前仍然會評估z。 – 2010-07-14 13:41:06

+0

@大衛:非常好的一點。 – 2010-07-14 13:52:12

0

例如,你的邏輯是這樣的:

if(a==x || a== y|| a==z) 
{ 
    DoSomething(); 
} 
else 
{ 
    DoOtherThings(); 
} 

意志等同於:

if(a!=x&& a != y && a!= z) 
{ 
    DoOtherThings(); 
} 
else 
{ 
    DoSomething(); 
} 

乾杯。

+1

:)這不是重點,你做了同樣的,但只是一個不同的形式,你只需要寫一次「一個」 – Omu 2010-07-14 11:01:54

+0

誤解! – 2010-07-14 11:21:59

5

考慮其中一個==X,和ÿŽ是慢到評估的,昂貴的功能的情況。

  • if(a == x || a == y || a == z)你有短路|| - 運算符的好處,所以你Ÿž將不進行評估。
  • 如果你與new[] { x, y, z }陣列 - Ÿž將每次評估

如果有一個優雅的語法來創建惰性評估序列(IEnumerable<T>),那麼使用.Contains()這個'技巧'會更有用。即類似yield return x; yield return y;...,但內聯和更短。

相關問題