我刚刚在
的行中写了一个if语句if (value == value1 || value == value2 || value == value3 || value == value4)
//do something
令我很生气,我总是要重复'value =='部分。在我看来,除了难以阅读之外,它没有任何目的。
我编写了以下ExtensionMethod,它应该使上面的场景更具可读性:
public static bool IsEqualToAny<T>(this T value, params T[] objects)
{
return objects.Contains(value);
}
现在我可以简单地写一下
if (value.IsEqualToAny(value1, value2, value3, value4))
//do something
这是ExtensionMethod的好用法吗?
编辑:
感谢所有出色的答案。记录:我保留了方法。虽然您可以简单地使用new []{value1,value2,value3,value4}.Contains(value)
的建议是正确的,但我只是更喜欢从左到右阅读这种if语句( 如果此值等于其中任何一个 < / strong>而不是 如果这些值包含此值 )。对于我来说,在每个对象的intellisense中再显示一个方法对我来说不是问题。
答案 0 :(得分:5)
为不受限制的T
编写扩展方法是不常见的。尤其是,这种方法很快就会使您的智能感知很难使用。
虽然有效,但我可能会将此作为扩展方法 - 可能只是使用标准的静态实用程序方法。
C#3数组初始化程序语法可能更容易吗?
bool isTrue = new[] { 1, 2, 3 }.Contains(3);
当然,对于大型数据集,您可能希望在某处缓存HashSet<T>
;-p
答案 1 :(得分:4)
您尚未添加仅对特定应用程序或上下文有用的功能,您的扩展名已明确命名,行为显而易见,无需查看实现。
答案是“是的,它是”
答案 2 :(得分:1)
对我来说很好看,虽然看起来有些不同寻常。
答案 3 :(得分:1)
看起来很公平,但我退后一步。你能在比较中加入任何商业意义吗?那些价值观是什么?也许你最好使用一个名为IsSpecialCustomerLocation
的方法或表达代码实际意图的方法。
答案 4 :(得分:1)
您还可以对该任务使用LINQ方法语法(通过使用System.Linq命名空间):
object[] objects = new object[10];
objects.Contains(new MyClass());
嗯,让我想一下......哦,你已经在使用它了。但是你把它放在一个单独的方法中而不是直接调用它。
答案 5 :(得分:1)
我会为此目的制作一个静态类。我不喜欢这个解决方案,因为它为所有类添加了一个看起来有点矫枉过正的方法。然而,它确实与OOD一起使用,因为您要求对象对自己执行功能(有点)。
不过,我会选择一个可重复使用的课程,因为我可以看到反模式是如何形成的。我还没有把它称为反模式,但如果弹出太多这些结构,我会称之为可读性的反模式,因为每个对象都会被扩展方法弄得乱七八糟。我有点像命名空间污染,但是班级成员污染。
if (ConditionHelper.IsEqualToAny(value, value1, value2, value3))
{
// Do something
}
做同样的工作,不污染任何东西。
答案 6 :(得分:1)
你真的打算做包含并保证你会在所有可能的对象上应用Contains吗?你可以使用这种扩展方法吗?
如果某些给定对象通过重载operator ==来测试相等性,那么您的通用解决方案将失败。这使它不是多个==测试的真正等价物。这也是编写扩展方法的危险的一个很好的例子!
以下Linq代码在您实现运算符重载时以及使用默认==意味着比较对象引用时工作,假设该值实际上是与value1,2,3或4相同的对象,给定V作为此特定情况下值的对象类型:
V[] lv = { value, value2, value3, value4 };
if (lv.Any( v => v==value))
// do something
或简称:
if (new List<V>{value, value2, value3, value4 }.Any( v => v==value))
// do something
我无法将上述lambda表达式用于通用扩展方法。
作为一个很好的(如果不相关的)我认为是一个可爱,可读的语法的例子,Python中的成语将是
if value in (value1, value2, value3, value4):
答案 7 :(得分:0)
如果您只检查枚举值(正如您在罗杰斯答案评论中所述),您应该在枚举上使用FlagsAttribute。
[Flags]
public enum Value
{
Value1 = 0,
Value2 = 1,
Value3 = 2,
Value4 = 4
}
Value value = Value.Value1;
if (value | Value.Value1 | Value.Value2 | Value.Value3 | Value.Value4)
{
// You can also use other bitwise operations, like & (AND), ^ (XOR) and ~ (NOT)
}
否则;如果是特定于域的,请将其添加到业务逻辑中。如果它是通用的,请创建一个帮助类。