10

我刚刚在以下行中写了一个 if 语句

if (value == value1 || value == value2 || value == value3 || value == value4)
    //do something

我总是不得不重复“价值==”部分,这让我很恼火。在我看来,除了使它难以阅读之外,这没有任何目的。

我编写了以下 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 语句(如果这个值等于其中任何一个,而不是这些值是否包含这个值)。在每个对象的智能感知中显示另一种方法对我来说不是问题。

4

8 回答 8

5

为不受限制的T. 尤其重要的是,这种方法很快就会让你的智能感知变得非常难以使用。

虽然有效,但我可能会避免将其作为扩展方法- 也许只使用标准的静态实用程序方法。

C# 3 数组初始值设定项语法可能更简单?

bool isTrue = new[] { 1, 2, 3 }.Contains(3);

当然,对于大型数据集,您可能希望在HashSet<T>某处缓存一个 ;-p

于 2009-02-11T09:22:44.877 回答
4

您尚未添加仅对特定应用程序或上下文有用的功能,您的扩展已明确命名并且行为很明显,无需查看实现。

答案是“是的,是的”

于 2009-02-11T09:22:43.020 回答
1

对我来说看起来不错,虽然它看起来有点不合常规。

于 2009-02-11T09:16:55.157 回答
1

这似乎很公平,但我会退后一步。你能把任何商业意义放在比较中吗?这些价值观是什么?也许你最好使用一个被调用的方法IsSpecialCustomerLocation或表达代码实际意图的东西。

于 2009-02-11T09:17:03.597 回答
1

您还可以对该任务使用 LINQ 方法语法(通过使用 System.Linq 命名空间):

            object[] objects = new object[10];
        objects.Contains(new MyClass());

嗯,让我想一想……哦,你已经在使用它了。但是您已将其放在单独的方法中,而不是直接调用它。

于 2009-02-11T09:19:35.790 回答
1

我会为此目的制作一个静态类。我不喜欢那个解决方案,因为它为所有类添加了一个方法,这似乎有点矫枉过正。然而,它在某种程度上与 OOD 一致,因为您要求对象对自己执行功能(有点)。

尽管如此,我还是会选择一个可重用的类,因为我可以看到反模式是如何形成的。我还没有将其称为反模式,但如果出现太多这些结构,我会称其为可读性反模式,因为每个对象都会被扩展方法弄得杂乱无章。我有点像命名空间污染,但类成员污染。

if (ConditionHelper.IsEqualToAny(value, value1, value2, value3)) 
{
    // Do something
}

做同样的工作,不会污染任何东西。

于 2009-02-11T09:59:21.717 回答
1

您是否真的打算执行 Contains 并保证您将在可能使用此扩展方法的所有可能对象上应用 Contains?

如果某些给定对象通过重载 operator== 来测试相等性,那么您的通用解决方案将失败。这使得它不是多个 == 测试的真正等价物。这也是编写扩展方法危险的一个很好的例子!

以下 Linq 代码在您实现运算符重载时以及如果您使用比较对象引用的默认 == 含义时起作用,也就是说 value 实际上是与 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):
于 2009-02-11T10:21:15.673 回答
0

如果您只检查 Enum 值(正如您在 Rogers 答案的评论中所说),您应该在 Enum 上使用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)
}

除此以外; 如果它是特定于域的,请将其添加到您的业务逻辑中。如果它是通用的,请创建一个辅助类。

于 2009-05-17T22:07:38.930 回答