在C#中是否有更简单的方式来编写这个if语句?

3

我有以下内容:

if (model.PartitionKey.Substring(2, 2) == "05" || 
    model.PartitionKey.Substring(2, 2) == "06")

我有更多类似的内容。有没有更干净的方法编写代码,不必重复两次model.PartitionKey?


1
Anne,你应该明确需要它的原因。是因为性能吗?代码可读性?为了方便扩展(例如使用来自配置的值进行比较)?回答往往朝着不同的方向,但它们经常不兼容。 - Adriano Repetti
7个回答

11

这个怎么样:

if (new string[]{"05", "06"}.Contains(model.PartitionKey.Substring(2, 2))
    // ...

那么你可以自由地将你要查找的字符串存储在一个漂亮的列表中...

var lookingFor = new string[]{"05", "06"};
var substring = model.PartitionKey.Substring(2, 2);
if (lookingFor.Contains(substring))
{
    // ...
}

如果你要查找的字符串列表超过两个,这将非常有帮助... 另外,你可以将其添加到一个集合中(HashSet<string>),以获得更高效的查找-但首先进行测试,因为开销可能会抵消收益。


你也可以将 new string[] { ... } 简写为 new [] { ... } - Stefan Steinegger
@Joey,哈哈!喜欢你的代码编辑注释 ;) 我想知道那些引号是怎么被搞砸的... - Daren Thomas

9

对于这种情况,我使用扩展方法。

public static bool In<T>(this T source, params T[] list)
{
   if (source = null)
       throw new NullReferenceException("Source is Null");

   return list.Contains(source);
}

调用它作为

if (model.PartitionKey.Substring(2, 2).In("05", "06"))

作为扩展方法,我们可以针对所有类型调用它,例如:
if(myintegervariable.In(3, 4));

或者

if(mybytevariable.In(23, 56, 34, 43, 87, 155));

1
这个扩展方法非常可重复使用。虽然它只是Contains的反向操作,但在像这样的情况下,它更加易读。 - Stefan Steinegger
1
我已经为自己创建了这个。那是最受欢迎的扩展方法。https://dev59.com/G3VC5IYBdhLWcg3whBaj#833477 - Tim Schmelter

7
var keyString = model.PartitionKey.Substring(2, 2);
if (keyString == "05" || keyString == "06")
{
    // ...
}

3
OP只是希望避免重复两次model.PartitionKey。把这个操作做一次然后保存结果,如何不算是优化? - Surfbutler
1
Tim,James:它完全符合问题(“不必重复model.PartitionKey两次”),将公共子表达式提取到本地变量中是一种可行的优化。我认为这并不难阅读 - temp 是什么很清楚,特别是在如此接近的情况下,条件确实更容易阅读。 - Joey
2
@Joey:temp不是一个好的命名方式。考虑到这个变量可能会在一个很大的方法中使用。关键是,modelPkYear会更加安全可靠。 - Tim Schmelter
1
@Surfbutler:但是你已经在15分钟前写下了你的答案。所以你有15分钟的时间来改进它。 - Tim Schmelter
1
现在将变量名更改为'keyString' :) - Surfbutler
显示剩余6条评论

5
我很惊讶没有人提供"switch"作为可能的替代方案 :)
switch (model.PartitionKey.SubString(2,2)) {
  case "05":
  case "06":
    // do stuff
    break;
  // other cases
  default:
    // like an else
}

您可以在MSDN上了解更多相关的IT技术内容。


1
+1 是为了引入一些完全不同的东西。问题是,这个问题不够清晰,以至于我们不知道这个解决方案是否适用。如果还有更多的常量需要比较,这可能是一个非常好的解决方案。 - Stefan Steinegger
1
我觉得将现有的代码替换为switch语句并不能让OP的生活更轻松。如果有什么影响,这可能会成为更多的障碍,因为要在各个地方编写switch语句。除非当然它被封装到可重用的方法中。 - James

3
你可以将子字符串保存在一个变量中:
```

你可以将子字符串保存在一个变量中:

```
var substring = model.PartitionKey.Substring(2, 2);
if (substring == "05" || substring == "06")

或者您可以使用正则表达式:

if (Regex.IsMatch("^..0[56]", model.PartitionKey))

这可能有点取决于您阅读代码时对正则表达式的理解程度。

6
对于正则表达式的情况,我认为在像这样的简单字符串操作中不应该使用正则表达式。如果使用正则表达式反而会使语句更加复杂。 - James
1
如果我选择这条路线,我会使用更简单的正则表达式,例如 ^..(?:05|06)。同时请注意,在某些语言中,.不匹配所有字符的情况。 - user166390
詹姆斯,我认为这很主观。在这种情况下,我宁愿阅读一个简单的正则表达式(这是很容易理解的)而不是更复杂的语句。但是,正如我所说的,这在一定程度上取决于您对正则表达式的熟悉程度。 - Joey
pst,引入非捕获组比字符类更加混乱,我想。 - Joey
一般来说,我宁愿阅读一个简单的正则表达式。当然,这是主观的。然而,在这种特定情况下,将原始表达式称为“复杂”语句是相当牵强的。 - Christian.K
@Joey/pst - 我确实说了 IMO,但是总的来说,我仍然不相信为像这样微不足道的事情推荐正则表达式是一个更简单的选择。不仅如此,而且还可能会根据正则表达式的强度影响性能。 - James

1
为了提高可读性,您可以将Substring提取到一个变量中,然后进行测试:
var partitionKeyBits = model.PartitionKey.Substring(2, 2);

if (partitionKeyBits == "05" || partitionKeyBits == "06") {

}

但除此之外,就是这样了。


0

if (new []{"05", "06"}.Contains(model.PartitionKey.Substring(2, 2)))

语法可能有些偏差,欢迎纠正 :)

编辑:new []


1
数组创建缺少 new [] - Stefan Steinegger
1
同意这个方法去除了重复的 model.PartitionKey.Substring,但感觉不太符合 ".NET" 的风格(特别是需要使用 new[])。不确定从可读性的角度来看,这是否是一个好的选择。 - Michael Shimmins
1
话说,如果您能够这样做['05, '06'].include? model.PartitionKey.Substring(2,2),那就太棒了 ;) - Michael Shimmins
谢谢Michael。实际上,这就是我最初想到的...不过它们实际上差不多吧? - Orkun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接