2010-10-11 71 views
59

任何更简单的方法来写这个if语句?如果语句匹配多个值

if (value==1 || value==2)

例如...在SQL你可以说where value in (1,2)而不是where value=1 or value=2

我正在寻找的东西,会与任何基本类型...字符串,整数工作等

+2

更容易是个人偏好。就个人而言,我不认为它比'value == 1 ||更容易值== 2'。 – 2010-10-11 14:51:58

+1

@Joel:这很容易,但对于习惯于说“我希望成为1或2”的人来说,并不直观。事实证明,有一些语言可以精确地实现这种语法;比如IBI的FOCUS查询语言。 – 2010-10-11 14:53:51

+0

@Steven Sudit - 在这方面的“直觉”归结为个人喜好。 – 2010-10-11 15:04:43

回答

86

如何:

if (new[] {1, 2}.Contains(value)) 

这是一个黑客虽然:)

或者,如果你不介意创建自己的扩展方法,您可以创建以下文件:

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

你可以这样使用它:

if (1.In(1, 2)) 

:)

+7

我不认为第一个建议真的是黑客,因为它对我来说似乎相当优雅,特别是如果它是在大多数人通过'IsOneOfACertainType(typeToCheck)调用的背景中的代码;'例如 – Coops 2013-10-30 10:07:41

+2

不要忘记包括'使用System.Linq;'使用'Contains'。 – 2016-03-24 14:27:58

+1

*真*看起来像Python! – Panzercrisis 2017-08-04 20:05:56

6

如果你有一个列表,你可以使用。载有(yourObject),如果你只是寻找它存在(像一个地方)。否则看看Linq .Any()扩展方法。

3

一般来说,没有。

是的,在某些情况下,列表在ArrayList,但这不是一般情况。

22

这是你在找什么?

if (new int[] { 1, 2, 3, 4, 5 }.Contains(value)) 
5

使用LINQ,

if(new int[] {1, 2}.Contains(value))

但我不得不认为你原来如果是快。

+0

这两者之间的性能差异几乎肯定无关紧要。原文更具可读性,并且惯用。当然,可以编写'Enumerable.Range(0,10).ToList()。ForEach(x => Console.WriteLine(x));'而不是'for(int i = 0; i <10; i ++){ Console.WriteLine(ⅰ); }'但这只会让人不满。 “没有人写过让'6'成为一个群体。” – jason 2010-10-11 15:06:50

+0

@Jason - 我同意如果我看到我在生产代码中写的东西,我会生气。更像是“一条线来解释做法”,而不是“完全遵循”。真的,我同意建议转换语句的人。 – 2010-10-11 15:54:54

33

模仿SQL的 'IN' 更复杂的方式:):

public static class Ext {  
    public static bool In<T>(this T t,params T[] values){ 
     foreach (T value in values) { 
      if (t.Equals(value)) { 
       return true; 
      } 
     } 
     return false; 
    } 
} 

if (value.In(1,2)) { 
    // ... 
} 

但去的标准方式,它更具有可读性。

编辑:一个更好的解决方案,根据@了Kobi的建议:

public static class Ext {  
    public static bool In<T>(this T t,params T[] values){ 
     return values.Contains(t); 
    } 
} 
+0

需要一个返回类型,但扩展方法是我所建议的 – 2010-10-11 14:56:26

+1

@Daniel:是的,修正了,谢谢:) – 2010-10-11 14:57:04

+0

+1。好的解决方案,就像我的,但你的使用泛型。我会用你的替换我:) – goenning 2010-10-11 15:02:57

1

使用扩展方法:

public static class ObjectExtension 
{ 
    public static bool In(this object obj, params object[] objects) 
    { 
     if (objects == null || obj == null) 
      return false; 
     object found = objects.FirstOrDefault(o => o.GetType().Equals(obj.GetType()) && o.Equals(obj)); 
     return (found != null); 
    } 
} 

现在你可以这样做:

string role= "Admin"; 
if (role.In("Admin", "Director")) 
{ 
    ... 
} 
0
public static bool EqualsAny<T>(IEquatable<T> value, params T[] possibleMatches) { 
    foreach (T t in possibleMatches) { 
     if (value.Equals(t)) 
      return true; 
    } 
    return false; 
} 
public static bool EqualsAny<T>(IEquatable<T> value, IEnumerable<T> possibleMatches) { 
    foreach (T t in possibleMatches) { 
     if (value.Equals(t)) 
      return true; 
    } 
    return false; 
} 
5

另外,这会给你更多的灵活性,如果测试不是在未来1或2的其他值,是使用switch语句

switch(value) 
{ 
case 1: 
case 2: 
    return true; 
default: 
    return false 
} 
+0

我甚至不会说“或者”,这是最接近于SQL使用IN的例子(在包含子查询的结果中包含“Contains()”等)。 – 2010-10-11 15:11:31

1

更容易是主观的,但也许switch语句会更容易?你不必重复变量,所以更多的值可以适合该行,并且具有多个比较的行比使用if语句的对应更清晰。

1

的extensionmethod这样会做到这一点...

public static bool In<T>(this T item, params T[] items) 
{ 
    return items.Contains(item); 
} 

使用方法如下:

Console.WriteLine(1.In(1,2,3)); 
Console.WriteLine("a".In("a", "b")); 
1

在vb.net或C#我期望最快的一般方法来比较对任何合理数量的单独命名的对象(而不是集合中的所有东西)进行变量变换将简单地比较每个对象与比较值,就像你已经完成的那样。当然可以创建一个集合的实例并查看它是否包含对象,并且这样做可能比单独比较对象与所有项目更具表现力,但除非使用编译器可以明确识别的构造,否则这样的代码几乎肯定会比简单地进行单个比较慢得多。如果代码的性质每秒最多可以运行几百次,我不会担心速度,但是我会警惕代码被重新用于比原本运行更频繁的事情。

如果变量类似于枚举类型,另一种方法是选择幂次幂枚举值以允许使用位掩码。如果枚举类型有32个或更少的有效值(例如,开始Harry = 1,Ron = 2,Hermione = 4,Ginny = 8,Neville = 16),可以将它们存储在一个整数中并且一次检查多个位操作((if((thisOne &(Harry | Ron | Neville | Beatrix))!= 0)/ *执行某些操作* /这将允许快速代码,但仅限于具有少量值的枚举。

一个稍微强大一点的方法,但必须谨慎使用的方法是使用一些值来指示某些属性,而其他位标识该项,例如,位30可以指示一个字符是男性,第29位可以指示Harry的朋友等,而低位可以区分不同的字符,这种方法可以添加可能或不可能成为Harry朋友的角色,而不需要代码来检查朋友的哈利改变。这样做的一个警告是,必须区分用于设置枚举值的枚举常量和用于测试枚举值的枚举常量。例如,要设置一个变量来表示Harry,可能需要将其设置为0x60000001,但要查看变量是Harry,应该用0x00000001对它进行位测试。

另一种方法,如果可能值的总数是中等的(例如16-16,000左右),则可能有用的是具有与每个值相关联的标记数组。然后可以编写一些类似于“if(((characterAttributes [theCharacter] & chracterAttribute.Male)!= 0)”这样的方法,当字符的数量相当小时,这种方法效果最好,如果数组太大,缓存未命中可能会变慢下来的代码到测试针对少数字符的点如果你搜索在固定的值列表好几倍的价值,HashSet的<牛逼>单独会更快。

4

应使用,甚至只是为了HashSet,因为它在二进制搜索树中存储/搜索数据。

HashSet<int> nums = new HashSet<int> { 1, 2, 3, 4, 5 }; 
// .... 
if (nums.Contains(value)) 
0

我有同样的问题bu t用开关语句解决它 开关(您正在打开的值) { case 1: 您想要发生的代码;案例2: 您想要发生的代码; 默认值: 返回值 }