For what it's worth, the code in the OP is not a mess because it uses tuples, but because the values โโin the tuple are too weakly typed. Compare the following:
List<Pair<Integer, Integer>> products_weak = blah1(); List<Pair<Product, Integer>> products_strong = blah2();
I would also be upset if my development team walked around identifiers, not class instances, because an integer can represent anything .
With that said, tuples are extremely useful if you use them correctly:
- Correlations exist to group special values โโtogether. They are certainly better than creating an excessive amount of wrapper classes.
- A useful alternative to out / ref parameters when you need to return more than one value from a function.
However, tuples in C # make my eyes water. Many languages, such as OCaml, Python, Haskell, F #, etc., have special, concise syntax for defining tuples. For example, in F #, a module defines a constructor as follows:
val of_list : ('key * 'a) list -> Map<'key,'a>
I can create an instance of the map using:
(* 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
The same code in C # is ridiculous:
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);
I do not believe that there is anything wrong with tuples, but the C # syntax is too cumbersome to make the most of them.