C# 7.3 ValueTuple - проверка по умолчанию после деструктуризации
Я имею
(string name, int val) f(bool ok) {
if (!ok) return default;
return ('John', 5);
}
Я то делаю где то
var result = f(true);
if (result==default) return false;
var (name, val) = result;
... do something with name & val
Я нахожу это запутанным и чрезмерно многословным.. Я только создаю result
для проверки по умолчанию - в противном случае она мне не нужна... есть ли более элегантный способ проверки по умолчанию без использования result
промежуточная переменная?
Я могу сделать:
var (name, val) = f(true);
if ((name, val)==default) return false;
... do something with name & val
но опять же это утомительно, особенно если у ValueTuple много аргументов...
РЕДАКТИРОВАТЬ:
Теперь я понимаю, что приведенный выше код не только многословен, но и общий паттерн ошибочен - вы не можете использовать default как замену состояния ошибки, так как ValueTuples объясняется тем, что для некоторых ValueTuple - то есть (int, int) - невозможно отличить значение по умолчанию от другого действительного значения - т.е. (0, 0) и т. д.
4 ответа
Я закончил тем, что сделал:
private (bool ok, string name, int val) F(bool ok) {
if (!ok) return (false, "", 0);
return (true, "John", 5);
}
var (ok, name, val) = F(true);
if (!ok) return;
.. continue
У языка нет более лаконичного способа достичь того, чего вы хотите
Тем не менее, другой подход заключается в использовании Try Pattern
private static bool TryF(bool ok, out (string name, int val) result)
{
if (!ok)
{
result = default;
return false;
}
result = ("John", 5);
return true;
}
...
if (!TryF(false, out var result))
return;
// continue
Вы можете использовать следующее.
var (name,val) = f(true);
if ((name, val) == default)
Вы можете вернуть обнуляемый кортеж. Это немного более элегантно, чем возвращение кортежа по умолчанию, но хуже, чем ответ TryXXX Майкла Рэндалла.
private static (string name, int val)? F(bool ok) {
if (!ok) return null;
return ("John", 5);
}
var result = F(true);
if (result == null)
return;
var (name, val) = result.Value;