Как уже писали другие, кортежи C # 4 являются хорошим дополнением, но ничто не может принуждать к использованию, если нет механизмов распаковки. Что я действительно требую от любого типа, который я использую, так это ясность того, что он описывает, по обе стороны протокола функций (например, вызывающий, вызывающий стороны) ... как
Complex SolvePQ(double p, double q)
{
...
return new Complex(real, imag);
}
...
var solution = SolvePQ(...);
Console.WriteLine("{0} + {1}i", solution.Real, solution.Imaginary);
Это очевидно и ясно как для вызывающей, так и для вызываемой стороны. Однако это
Tuple<double, double> SolvePQ(double p, double q)
{
...
return Tuple.Create(real, imag);
}
...
var solution = SolvePQ(...);
Console.WriteLine("{0} + {1}i", solution.Item1, solution.Item2);
Не оставляет ни малейшего понятия о том, что это решение на самом деле (хорошо, строка и имя метода делают это довольно очевидным) на сайте вызова. Item1 и Item2 одного типа, что делает подсказки бесполезными. Единственный способ узнать наверняка - это «перепроектировать» свой путь обратно через SolvePQ
.
Очевидно, что это неправдоподобно, и у всех, кто занимается серьезными числовыми вещами, должен быть тип Complex (например, в BCL).
Но каждый раз, когда вы получаете разделенные результаты, и вы хотите дать этим результатам разные имена ради readability , вам нужно распаковать кортежи. Переписанные две последние строки будут:
var (real, imaginary) = SolvePQ(...); // or var real, imaginary = SolvePQ(...);
Console.WriteLine("{0} + {1}i", real, imaginary);
Это не оставляет места для путаницы, кроме как привыкнуть к синтаксису.