这是ExtensionMethod的好用吗?

时间:2009-02-11 09:14:44

标签: c# extension-methods

我刚刚在

的行中写了一个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中再显示一个方法对我来说不是问题。

8 个答案:

答案 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)
}

否则;如果是特定于域的,请将其添加到业务逻辑中。如果它是通用的,请创建一个帮助类。