Поскольку другие ответы хорошо освещены: речь идет не о производительности, а о ясности.
Широкая поддержка обеих ваших опций:
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
if (acceptedValues.All(v => v != someValue))
{
// exception logic
}
Но я думаю, что это может обеспечить более широкую поддержку :
var isValueAccepted = acceptedValues.Any(v => v == someValue);
if (!isValueAccepted)
{
// exception logic
}
Просто вычисляя логическое (и именовав его), прежде чем отрицать что-либо, все это проясняет мне много.
В этой статье ничего не говорится о «изменении входной переменной и восстановлении вывода в той же самой переменной» , в ней только говорится, что не очевидно, какие аргументы могут быть изменены вызовом функции :
int x{};
int y{};
foo(x, y); // can you guess which variable has changed?
Часть о передаче по адресу, имеющая «более четкий синтаксис, указывающий, является ли параметр изменяемым или нет», является полной фигней. Он не только страдает от той же проблемы, что и передача по ссылке, но также подразумевает, что некоторые аргументы могут быть необязательными и возможной передачей права собственности
int x{};
int y{};
foo(&x, &y); // can you guess which variable has changed?
foo(nullptr, &y); // can you guess whether this is correct usage?
foo(&x, &y); // can you be sure that foo won't delete pointer to x?
Чтобы быть в безопасности, можно использовать что-то вроде явной передачи по (постоянная) ссылка:
int x{};
int y{};
foo(::std::as_const(x), y); // alright, x should not be changed inside
int x = 5;
foobar(x);
Какое значение x
после вызова функции? Большинство людей ожидают, что оно все еще будет 5
, поскольку, за исключением неопределенного поведения, оно не может измениться при передаче по значению. В C нет даже передачи по ссылке, поэтому значение всегда будет 5
. Теперь в C ++ внезапно происходит передача по ссылке, и только из этого фрагмента кода вы не можете узнать, изменится ли x
после вызова функции. Для этого вам нужно взглянуть на фактическую подпись foobar
.
Сам по себе он не «опасен», но при плохом использовании может привести к неясному и вводящему в заблуждение коду. Особенно, если у вас есть набор параметров, некоторые из которых не соответствуют параметрам, а некоторые нет, а некоторые имеют вводящие в заблуждение имена. В вашем примере имена параметров содержат out
, чтобы указать, что они являются выходными параметрами, и это хороший стиль, который уменьшает эту опасность.
Сравните это со следующим фрагментом отсюда , объясняющим передачу по ссылке, как это происходит в C #:
void Method(ref int refArgument)
{
refArgument = refArgument + 44;
}
int number = 1;
Method(ref number);
Console.WriteLine(number);
// Output: 45
Здесь вы сразу видите, что он передается по ссылке, потому что он говорит ref number
.