Есть много способов справиться с этим, но позвольте мне выбрать несколько.
Во-первых, есть случай, когда все критерии (все AND-критерии в вашем операторе if) + код, который нужно выполнить, если все они истинны, являются одноразовыми.
В этом случае используйте ваш код. Возможно, вы захотите сделать то, что несколько других уже предложили, переписать, чтобы использовать код типа Guard-clause.
Другими словами, вместо этого:
if (a && b && c && d && ......)
DoSomething();
... вы переписываете что-то похожее на это:
if (!a) return;
if (!b) return;
if (!c) return;
if (!d) return;
if (!...) return;
DoSomething();
Почему? Потому что, как только вы начинаете вводить OR-критерии в микс, становится трудно читать код и выяснять, что произойдет. В приведенном выше коде вы разделяете критерии для каждого оператора AND (&&), и, таким образом, код становится проще для чтения. По сути, вы переписываете код, говоря «если и то, и то, или другое, и третье, или что-то другое, то делаете что-то« чтобы быть », если это, затем выходите; если это другое; затем выходите; если некоторые другое дело, затем выход; если ничего из вышеперечисленного, сделать что-то ".
Однако во многих случаях у вас также есть случай повторного использования. Если некоторые из этих критериев появятся где-то еще, но код, который будет фактически выполняться (DoSomething), не будет таким же, то я бы снова обратился к тому, что уже предложили другие. Перепишите критерии в методы, которые возвращают результат Boolean
в зависимости от результата оценки критериев.
Например, что легче читать, это?
if (a && b && c && d && e && f && (h || i) && (j || k) || l)
или это:
if (CanAccessStream() && CanWriteToStream())
при условии, что все эти буквы можно разделить на эти два критерия.
В этом случае я бы взял некоторые критерии и включил в эти методы и выбрал подходящее название для критериев.
Третий вариант - это когда критерии различаются в нескольких местах кода, но фактический код для выполнения остается тем же.
В этом случае я бы переписал так, чтобы вы сгруппировали критерии и наслоили методы так, чтобы вызов одного метода проверил некоторые критерии, а затем вызвал другой метод, который проверит некоторые другие критерии и т. Д.
Например, вы могли бы написать это:
if (stream != null && buffer != null && inBuffer > 0 && stream.CanWrite)
stream.Write(buffer, 0, inBuffer);
else
throw new InvalidOperationException();
или вы могли бы написать это:
if (inBuffer > 0)
{
Debug.Assert(buffer != null);
WriteToStream(buffer, inBuffer);
}
...
private void WriteToStream(Byte[] buffer, Int32 count)
{
if (stream.CanWrite)
stream.Write(buffer, 0, count);
else
throw new InvalidOperationException();
}
Я бы сказал, что второй способ легче читать и более пригоден для повторного использования, чем первый.