Тестирование переменной для нескольких значений? - PullRequest
4 голосов
/ 17 января 2012

Я помню, как видел здесь вопрос об этой же проблеме, где такие вещи, как:

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)...

Ответы [ 3 ]

6 голосов
/ 17 января 2012

Это, безусловно, неэффективно в теории, как прямой тест if, но это красная сельдь. Реальный вопрос: тебе не все равно?

У этого вопроса есть две стороны.

  1. Так что, если он медленнее? Если вы не выполняете это в цикле, связанном с процессором, который выполняется миллион раз, разница чисто теоретическая. Используйте все, что угодно, чтобы получить больше кода без ошибок, который приятно читать и поддерживать.
  2. Так что, если это уродливее? Вы собираетесь писать это много раз? Конечно, нет - если вы намереваетесь использовать много раз, поместите его в метод с хорошим именем и никогда больше не думайте об этом.

Что касается подхода LINQ, он немного короче и немного читабельнее, чем у вас:

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

Возможно, вы захотите написать другой метод расширения, который позволит вам вызывать его с обратным положением операнда, например,

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

Вердикт: Я бы пошел с LINQ для более чем 3 или около того значений для проверки при условии, что нет другого более очевидного способа проверить эти значения (например, в этом случае IsNullOrWhiteSpace очень близко), и нет никаких очевидных последствий для производительности. В противном случае if проверено и верно.

3 голосов
/ 17 января 2012

Не обязательно плохая практика, но есть и другие способы. Пара разных способов:

  1. Для пустых / пустых строк,

    String.IsNullOrEmpty(s.Trim());
    
  2. IsNullOrWhiteSpace в 4.0:

     String.IsNullOrWhitespace(s.Trim()); 
    
  3. для оператора, подобного SQL IN:

    if((new[] {" ", "  ", "\n"}).Contains(s))
    {
    }
    
1 голос
/ 17 января 2012

Эти вопросы стиля редко бывают абсолютными и во многом зависят от конкретной решаемой проблемы, а также от организационных соображений и личных предпочтений. Тем не менее, одна уважаемая ссылка (Code Complete от Steve McDonnell) советует упростить сложные тесты с вызовами логических функций в качестве средства уменьшения сложности операторов 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 не обязательно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...