针对多个值测试变量

本文关键字:测试 变量 | 更新日期: 2023-09-27 18:20:25

我记得在这里看到过一个关于同一个问题的问题,其中的内容如下:

if( x==null || x==" " || x==" " || x=="'n")...

最后变成了又长又丑的绳子,但答案不太好,我不记得是什么了。

我正在学习MySQL教程,在SQL中解决问题的方法是使用关键字"in"。

WHERE value IN (1 , 22, 35)...

所以我想知道这是否被认为是低效或糟糕的做法:

object[] BadVals = {null, " ", "  ", "'n"};
if(Array.IndexOf(BadVals, x) != -1)...

针对多个值测试变量

它在理论上肯定不如直接的if测试有效,但这只是转移注意力。真正的问题是:你在乎吗

这个问题有两面性。

  1. 那么,如果速度慢一点呢?如果你不是在一个执行了一百万次的CPU绑定循环上运行这个,那么区别纯粹是理论上的。使用任何可以获得更多无错误代码的东西,这是阅读和维护的乐趣
  2. 如果它更丑呢?你会写很多次吗?当然不是——如果你打算多次使用,就把它放在一个命名良好的方法中,再也不要考虑它了

至于LINQ方法,它比现有的略短,可读性更强

if((new[] { null, " ", "  ", "'n" }).Contains(x)) ...

您可能想要编写另一个扩展方法,允许您在操作数位置反转的情况下调用它,例如

if(x.In(new[] { null, " ", "  ", "'n" })) ...

结论:如果没有其他更明显的方法来检查这些值(例如,在这种情况下,IsNullOrWhiteSpace非常接近),并且没有明显的性能影响,我会使用LINQ测试3个左右的值。否则,if被尝试并为真。

这不一定是糟糕的做法,但还有一些其他方法。有几种不同的方法:

  1. 对于空字符串,

    String.IsNullOrEmpty(s.Trim());
    
  2. 4.0中的IsNullOrWhiteSpace

     String.IsNullOrWhitespace(s.Trim()); 
    
  3. 对于像SQL IN:这样的运算符

    if((new[] {" ", "  ", "'n"}).Contains(s))
    {
    }
    

这些风格问题很少是绝对的,很大程度上取决于正在解决的具体问题,以及组织考虑和个人偏好。也就是说,一个备受推崇的参考文献(Steve McDonnell的Code Complete)建议用布尔函数调用来简化复杂的测试,以此来降低if语句的复杂性。例如,可以将上面的if语句替换为以下语句:

if (IsStringFoo(s)) {...}

其他定义为

// Returns true if and only if the input string is a Foo
bool IsStringFoo(string s)
{
    return s == "" || s == " " || s == "'n";
    // or use the alternate array syntax here instead if you prefer
}

这不仅向消费者传达了逻辑机制,还可能传达了这些机制的业务原理,从而可能提高可读性。

使用所提出的in语法可能会遇到类似的可读性问题——特别是,目前还不清楚为什么要进行这些特定的测试。后一种方法可能更难理解,因为"或"以Array.IndexOf不一定的方式传达布尔逻辑运算。