如果语句匹配多个值
任何更简单的方法来写这个if语句?
if (value==1 || value==2)
例如…在SQL中,你可以说where value in (1,2)
而不是在where value=1 or value=2
。
我正在寻找的东西,可以与任何基本的types…string,整型等
怎么样:
if (new[] {1, 2}.Contains(value))
这是一个黑客,虽然:)
或者,如果您不介意创build自己的扩展方法,则可以创build以下内容:
public static bool In<T>(this T obj, params T[] args) { return args.Contains(obj); }
你可以像这样使用它:
if (1.In(1, 2))
🙂
更复杂的方式:)模拟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)) { // ... }
但是去标准的方式,它更可读。
编辑 :更好的解决scheme,根据@ Kobi的build议:
public static class Ext { public static bool In<T>(this T t,params T[] values){ return values.Contains(t); } }
这是你想要的 ?
if (new int[] { 1, 2, 3, 4, 5 }.Contains(value))
如果你有一个列表,你可以使用.Contains(yourObject),如果你只是在寻找它存在(像一个地方)。 否则看看Linq。Any()的扩展方法。
或者,如果将来testing1或2以外的值,这将给你更多的灵活性,就是使用switch语句
switch(value) { case 1: case 2: return true; default: return false }
使用Linq,
if(new int[] {1, 2}.Contains(value))
但我不得不认为,你的原来如果更快。
如果您多次search固定值列表中的值,则应该使用HashSet <T> ,即使对于HashSet也是如此,因为它在二进制search树中存储/search数据。
HashSet<int> nums = new HashSet<int> { 1, 2, 3, 4, 5 }; // .... if (nums.Contains(value))
一般来说,不。
是的,有些情况下,列表是在Array
或List
,但这不是一般情况。
更容易是主观的,但也许switch语句会更容易? 你不必重复这个variables,所以更多的值可以适用于行,并且多行比较的行比使用if语句的行更清晰。
在vb.net或者C#中,我认为最快速的一般方法是将一个variables与任何合理数量的分开命名的对象(而不是集合中的所有东西)进行比较,将比较每个对象与比较正如你所做的那样。 当然可以创build一个集合的实例,看看它是否包含对象,这样比单独比较对象和对象更具有performance力,但除非有人使用编译器可以明确识别的构造,否则这样的代码几乎肯定会比简单地进行个别比较慢得多。 如果代码的性质每秒最多可以运行几百次,我不会担心速度,但是我会担心代码被重新用于比原本运行更频繁的事情。
另一种方法,如果一个variables类似于枚举types,就是select两次幂枚举值来允许使用位掩码。 如果枚举types有32个或更less的有效值(例如,开始Harry = 1,Ron = 2,Hermione = 4,Ginny = 8,Neville = 16),可以将它们存储在一个整数中,并且一次检查多个位操作((如果((thisOne&(Harry | Ron | Neville | Beatrix))!= 0)/ *做一些事情* /这将允许快速的代码,但是只限于具有less量值的枚举。
一个更强大的方法,但必须谨慎使用的方法是使用一些值来表示某些东西的属性,而其他位标识该项目。 例如,位30可以指示一个字符是男性,位29可以指示Harry的朋友等,而较低的位用于区分字符。 这种方法将允许添加可能或不可能是Harry的朋友的angular色,而不需要检查Harry朋友的代码改变。 这样做的一个警告是,必须区分用于设置枚举值的枚举常量和用于testing枚举值的枚举常量。 例如,要设置一个variables来表示Harry,可能需要将其设置为0x60000001,但要查看variables是否是Harry,则应该使用0x00000001进行位testing。
还有一种方法,如果可能值的总数是中等的(例如16-16,000左右),则可能有用的是具有与每个值相关联的标志arrays。 然后可以编写“if(((characterAttributes [theCharacter]&chracterAttribute.Male)!= 0)”这样的方法,当字符的数量相当小的时候效果最好,如果数组太大,caching未中可能会变慢下面的代码,以单独testingless数字符将更快。
使用扩展方法:
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")) { ... }
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; }
像这样的扩展方法会做到这一点…
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:你想要发生的代码; 情况2:你想要发生的代码; 默认值:返回值}