【问题标题】:C# - Prettier way to compare one value against multiple values in a single line of code [duplicate]C# - 在一行代码中将一个值与多个值进行比较的更漂亮的方法[重复]
【发布时间】:2018-10-27 10:23:21
【问题描述】:

我有这段代码:

if (filter != RECENT &&
    filter != TODAY &&
    filter != WEEK &&
    filter != MONTH &&
    filter != ALLTIME)
{
    filter = RECENT;
}

请注意,filterstring,它与 const string 类型进行比较。有什么办法可以内联并让它更具可读性吗?使用三元运算符并没有变得更好,因为我仍然需要重复 filter != XXXXX

filter = filter != RECENT &&
         filter != TODAY &&
         filter != WEEK &&
         filter != MONTH &&
         filter != ALLTIME ? RECENT : filter;

这显然行不通

filter = filter != RECENT && TODAY && WEEK && MONTH && ALLTIME ? RECENT : filter;

有没有更漂亮的方法(更漂亮==所有逻辑都必须在一行代码中)来做这个比较?更具体地说,是为了防止 filter != XXXXX 重复。

请注意,性能不是我对这个问题的主要关注点。

【问题讨论】:

  • 取决于Filter 实际上是什么。它是一个枚举吗?如果是这样,它是具有[Flags] 属性的枚举吗?
  • @elgonzo filter 只是一个string。它正在与常量进行比较,例如。 const string RECENT = "recent";.
  • 您可以将这些字符串放在一个数组中并使用 Linq。如果您随后进一步创建/使用带有params string[] ... 参数的静态方法(或者更好的扩展方法)(params string[] 参数将是我谈到的字符串数组),您可以将测试简化为@ 987654336@
  • 创建一个常量数组,然后 !array.Contains(filter) 或考虑使用 elgonzo 建议的枚举。我们不了解您的应用程序,但据我们所知,这可能是比比较字符串更好的做法。
  • 没错,在这种情况下建议 Linq 可能有点矫枉过正;数组类型提供的函数(例如Contains)可能就是你所需要的...

标签: c# comparison equality conditional-operator readability


【解决方案1】:

我更喜欢创建一个扩展方法。

  public static bool NotIn(this string filter , params string[] valuesToCompare)
    {
        var result = true;
        foreach (var item in valuesToCompare)
        {
            if (filter == item) return false;
        }
        return result;
    }

并使用类似

if( filter.NotIn("RECENT", "TODAY ", "WEEK ", "MONTH", "ALLTIME"))
  {
     filter = "RECENT";
  }

【讨论】:

  • 这种方法的缺点是在每个调用时创建一个数组。
  • 另外,foreach 可以替换为Contains
【解决方案2】:

请注意,此答案是在 OP 澄清他们只需要单行解决方案之前编写的。

使用哈希集

区分大小写的比较:

var filters = new HashSet<string>(new[] { RECENT, TODAY, WEEK, MONTH, ALLTIME });

if (!filters.Contains(filter))
{
    filter = RECENT;
}

不区分大小写的比较:

var filters = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
filters.UnionWith(new[] { RECENT, TODAY, WEEK, MONTH, ALLTIME });

if (!filters.Contains(filter))
{
    filter = RECENT;
}

使用字符串数组

区分大小写的比较:

string[] filters = {RECENT, TODAY, WEEK, MONTH, ALLTIME};

if (!filters.Contains(filter))
{
    filter = RECENT;
}

不区分大小写的比较:

string[] filters = {RECENT, TODAY, WEEK, MONTH, ALLTIME};

if (!filters.Contains(filter, StringComparer.OrdinalIgnoreCase))
{
    filter = RECENT;
}

编辑

可以使用三元运算符 ?: 代替 if 语句,但 IMO 会降低代码的可读性。此外,从调试的角度来看,在if 语句中设置断点以检查数组是否包含过滤器比使用运算符?: 设置断点更容易:

【讨论】:

    猜你喜欢
    • 2012-02-25
    • 2022-02-01
    • 1970-01-01
    相关资源
    最近更新 更多