Типичный способ вернуть эти результаты:
(bool success, string name1, string name2) MyFunc(bool param)
{
return param ? (true,"A","B")
:default;
}
Значение по умолчанию для bool
равно false, поэтому я могу быть ленивым и просто вернуть default
Вы можно использовать сопоставление с шаблоном is
для проверки и извлечения значений в одной чистой строке:
if(MyFunc(true) is (true,var name1,var name2)){
Console.WriteLine("AAA");
}
if(MyFunc(false) is (true,var name3,var name4)){
Console.WriteLine("Should never enter here");
}
Это будет печатать только "AAA"
Go стиль
Go использует кортежи для многозначных результатов в настоящее время так же, как и у них еще нет исключений. Это приводит к запутанному потоку управления и дает возможность игнорировать ошибки. Однако вместо флага последнее поле кортежа является сообщением об ошибке:
func f1(arg int) (int, error) {
if arg == 42 {
return -1, errors.New("can't work with 42")
}
return arg + 3, nil
}
...
if r, e := f1(i); e != nil {
fmt.Println("f1 failed:", e)
} else {
fmt.Println("f1 worked:", r)
}
То же самое можно сделать в C#, добавив поле error
в кортеж и сопоставив нуль :
(int i,string? error) F1(int arg)
{
return arg==42? (-1,"Can't work with 42")
:(arg+3,null);
}
...
var (i,error) =F1(42);
if (error is string err)
{
Console.WriteLine($"F1 failed: {err}");
}
else
{
Console.WriteLine($"F1 worked: {i}");
}
Или
switch (F1(42))
{
case (_,string error):
Console.WriteLine($"F1 failed: {error}");
break;
case (int i,null):
Console.WriteLine($"F1 worked: {i}");
break;
}
Или, с выражениями переключателя:
var output = F1(43) switch {
(_,string error)=>$"F1 failed: {error}",
(int i,null) =>$"F1 worked: {i}"
};
Console.WriteLine(output);