12 Answers
12

The upcoming 4.0 release of Microsoft
.NET Framework introduces a new type
called System.Tuple. System.Tuple is a
fixed-size collection of
heterogeneously typed data.

Like an array, a tuple has a fixed
size that can't be changed once it has
been created. Unlike an array, each
element in a tuple may be a different
type, and a tuple is able to guarantee
strong typing for each element.

There is already one example of a
tuple floating around the Microsoft
.NET Framework, in the
System.Collections.Generic namespace:
KeyValuePair. While KeyValuePair can be thought of as the same
as Tuple, since they are both
types that hold two things,
KeyValuePair feels different from
Tuple because it evokes a relationship
between the two values it stores (and
with good reason, as it supports the
Dictionary class).

Furthermore, tuples can be arbitrarily
sized, whereas KeyValuePair holds only
two things: a key and a value.

While some languages like F# have special syntax for tuples, you can use the new common tuple type from any language. Revisiting the first example, we can see that while useful, tuples can be overly verbose in languages without syntax for a tuple:

While the question is on MS providing it in .NET 4, this is a good way to manage it for now. +1
–
Chris CharabarukSep 30 '08 at 7:03

6

This inheritance approach is fine if you don't need to compare two Tuples for equality. I wanted to implement IEquatable<Tuple<T1, T2>> and so forth in my implementation, so I couldn't use inheritance, because I didn't want a Tuple<T1,T2> to be equal to a Tuple<T1,T2,T3,T4>.
–
Joel MuellerDec 3 '08 at 18:35

3

@Joel, You can have Equals check the dynamic type of both arguments.
–
RossFabricantApr 5 '09 at 17:49

How would you use it in code? t = new Tuple(1, 2); t.First and t.Second?
–
drozzyApr 30 '09 at 0:51

1

I see you use inheritance - do you really want to be able to pass a Tuple<T1,T2,T3> as a Tuple<T1,T2>? The answer is likely no.
–
Callum RogersApr 19 '13 at 15:44

Implementing Tuple classes or reusing F# classes within C# is only half the story - these give you the ability to create tuples with relative ease, but not really the syntactic sugar which makes them so nice to use in languages like F#.

For example in F# you can use pattern matching to extract both parts of a tuple within a let statment, eg

let (a, b) = someTupleFunc

Unfortunately to do the same using the F# classes from C# would be much less elegant:

Tuples represent a powerful method for returning multiple values from a function call without the need to litter your code with throwaway classes, or resorting to ugly ref or out parameters. However, in my opinion, without some syntactic sugar to make their creation and access more elegant, they are of limited use.

C# supports simple tuples via generics quite easily (as per an earlier answer), and with "mumble typing" (one of many possible C# language enhancements) to improve type inference they could be very, very powerful.

For what it is worth, F# supports tuples natively, and having played with it, I'm not sure that (anonymous) tuples add much... what you gain in brevity you lose very quickly in code clarity.

For code within a single method, there are anonymous types; for code going outside of a method, I think I'll stick to simple named types. Of course, if a future C# makes it easier to make these immutable (while still easy to work with) I'll be happy.

One of the benefits is for things like TryParse, where you can write 'valid value = double.TryParse("1.02")' and have multiple return values assigned without any clumsy out parameters. But in general I agree that purely positional data structures aren't a great thing to pass around.
–
Greg BeechSep 30 '08 at 7:45

2

Agreed - multiple return values is the best use case for tuples, and other than that there is very little purpose for tuples in code. That should be a convention rather than a restriction though where tuples are allowed. What I think would have been neater is if .NET languages provided a way to "disect" return objects into multiple values rather than introducing the tuple data type. Something like { j = ErrorCode, h = ResultObj } = SomeFunction() (where j and h are locals) would have been much more helpful than tuples.
–
Walt WOct 7 '10 at 19:07

Just like if statements are just gotos with a block of statements. Tuples are nice if you have you are used to them and classes seem unneccessary and unwieldy in specific cases...
–
Daniel WMar 10 '09 at 14:08

But that is not all. If it is based on inheritance, I suppose you could write Tuple<Int32, String> t1 = new Tuple<Int32, String, Boolean>(10, "a", true); etc. I'm not sure if there is any scenario this is desired.
–
nawfalJun 29 '14 at 8:45

I'd be surprised - C# is a strongly-typed language, whereas tuples are suited for more dynamically typed languages. C# has been drifting more dynamic as time goes on, but that's syntactic sugar, not a real shift in the underlying data types.

If you want two values in one instance, a KeyValuePair<> is a decent substitute, albeit clumsy. You can also make a struct or a class that'll do the same thing, and is expandable.

"C# has been drifting more dynamic" - no, it has been drifting more implicit/inferred; it is still a fully static language. However, better dynamic support (for consuming DLR classes) is a very likely future language enhancement.
–
Marc Gravell♦Sep 30 '08 at 7:30

2

How do you explain the presence of tuples in F#, or Haskell, or any of the other strongly and statically typed languages that have full support for them then...?
–
Greg BeechSep 30 '08 at 7:39