Why use tuples instead of objects?

后端 未结 10 1865
别那么骄傲
别那么骄傲 2020-12-24 05:29

The codebase where I work has an object called Pair where A and B are the types of the first and second values in the Pair. I find this object to be offensive, because it g

相关标签:
10条回答
  • 2020-12-24 05:51

    The obvious example is a coordinate pair (or triple). The labels are irrelevant; using X and Y (and Z) is just a convention. Making them uniform makes it clear that they can be treated in the same way.

    0 讨论(0)
  • 2020-12-24 06:00

    First of all, a tuple is quick and easy: instead of writing a class for every time you want to put 2 things together, there's a template that does it for you.

    Second of all, they're generic. For example, in C++ the std::map uses an std::pair of key and value. Thus ANY pair can be used, instead of having to make some kind of wrapper class with accessor methods for every permutation of two types.

    Finally, they're useful for returning multiple values. There's really no reason to make a class specifically for a function's multiple return values, and they shouldn't be treated as one object if they're unrelated.

    To be fair, the code you pasted is a bad use of a pair.

    0 讨论(0)
  • 2020-12-24 06:00

    For what its worth, the code in the OP is a mess not 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'd get upset too if my dev team were passing around IDs rather than class instances around, because an integer can represent anything.


    With that being said, tuples are extremely useful when you use them right:

    • Tuples exist to group ad hoc values together. They are certainly better than creating excessive numbers of wrapper classes.
    • 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 like OCaml, Python, Haskell, F#, and so on have a special, concise syntax for defining tuples. For example, in F#, the Map module defines a constructor as follows:

    val of_list : ('key * 'a) list -> Map<'key,'a>
    

    I can create an instance of a 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 equilvalent code in C# is ridicuous:

    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 don't believe there is anything wrong with tuples in principle, but C#'s syntax is too cumbersome to get the most use out of them.

    0 讨论(0)
  • 2020-12-24 06:01

    Scala has tuple-valued types, all the way from 2-tuples (Pairs) up to tuples with 20+ elements. See First Steps to Scala (step 9):

    val pair = (99, "Luftballons")
    println(pair._1)
    println(pair._2)
    

    Tuples are useful if you need to bundle together values for some relatively ad hoc purpose. For example, if you have a function that needs to return two fairly unrelated objects, rather than create a new class to hold the two objects, you return a Pair from the function.

    I completely agree with other posters that tuples can be misused. If a tuple has any sort of semantics important to your application, you should use a proper class instead.

    0 讨论(0)
提交回复
热议问题