2010-07-14 75 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;...,但内联和更短。

相关问题