Что бы ни стоило, код в OP является беспорядком не потому, что он использует кортежи, а потому, что значения в кортеже слишком слабо типизированы. Сравните следующее:
List<Pair<Integer, Integer>> products_weak = blah1();
List<Pair<Product, Integer>> products_strong = blah2();
Я бы тоже расстроился, если бы моя команда разработчиков передавала идентификаторы, а не экземпляры классов, потому что целое число может представлять что угодно .
С учетом вышесказанного, кортежи чрезвычайно полезны, когда вы правильно их используете:
- Существуют кортежи для группировки специальных значений вместе. Они, безусловно, лучше, чем создавать чрезмерное количество классов-оболочек.
- Полезная альтернатива параметрам out / ref, когда вам нужно вернуть более одного значения из функции.
Однако, кортежи в C # заставляют мои глаза слезиться. Многие языки, такие как OCaml, Python, Haskell, F # и т. Д., Имеют специальный краткий синтаксис для определения кортежей. Например, в F # модуль Map определяет конструктор следующим образом:
val of_list : ('key * 'a) list -> Map<'key,'a>
Я могу создать экземпляр карты, используя:
(* val values : (int * string) list *)
let values =
[1, "US";
2, "Canada";
3, "UK";
4, "Australia";
5, "Slovenia"]
(* val dict : Map<int, string> *)
let dict = Map.of_list values
Эквивалентный код в C # нелеп:
var values = new Tuple<int, string>[] {
new Tuple<int, string>(1, "US"),
new Tuple<int, string>(2, "Canada"),
new Tuple<int, string>(3, "UK"),
new Tuple<int, string>(4, "Australia"),
new Tuple<int, string>(5, "Slovenia")
}
var dict = new Dictionary<int, string>(values);
Я не верю, что с кортежами что-то не так в принципе , но синтаксис C # слишком громоздок, чтобы использовать их максимально эффективно.