Since C# 7 introduces value tuples, is there a meaningful scenario where they are better suited than tuples?
For example, the following line
collection.Select((x, i) => (x, i)).Where(y => arr[y.i].f(y.x)).ToArray();
makes the following line
collection.Select((x, i) => new {x, i}).Where(y => arr[y.i].f(y.x)).ToArray();
redundant.
What would be the use case where one is better used over the other (for either performance reasons or optimization)?
Obviously, if there is a need for more than six fields, tuples cannot be used, but is there something a bit more nuanced to it?
Current answer by @poke is correct and notes differences between tuple and anonymous types. I'm going to discuss why you would still use them or prefer one over another.
There are two new c# 7 features that retires anonymous types. ValueTuples and Records.
The main reason that you would not use anonymous types is
dynamic
object which has significant performance overheadReasons that you prefer tuple over anonymous types.
they are type safe all over the place. (regardless of naming)
they can be used as method arguments, type arguments, field and pretty much every where. (yes I said pretty much, there are places that needs to adopt with tuples, its matter of time.)
since they can be used as type argument, you probably prefer to wrap lightweight set of parameters in single parameter. like
Stack<(min, mid, max)>
you can change items naming when ever you feel its appropriate, in generic context name
item
may satisfy and in more specific context you need more specific name too, likecar
they are implicitly convertible,
int, int
can be assigned to(int, long)
without explicit cast.they are used in Deconstructs. which brings a lot of syntactic sugar to language.
you can have multiple assignments and declarations like
(int x, int y) = (0, 1)
Having all of this features, there is still one reason that you may prefer anonymous type over tuple.
but what if you want to use anonymous type globally? do you prefer to have dynamic objects or statically typed objects?
The incoming Records feature again defeats anonymous types. with records you define your class in short, concise and convenient way. not a big deal. just a single line
Type safety all over the place, and you also have reference type in hand. these two new features bring every thing to defeat anonymous types.
Note that Records are not added yet, we just have to wait.
Only remaining real usage of anonymous types will be
they still serve as backward compatible feature
they can be used in Linq queries when you use anonymous type locally. hence I don't say anonymous types are redundant.
As I said ValueTuples are not compatible with every component yet. its just matter of time, but this is how its going to be like in future.
enough arguments. in my humble opinion usage of anonymous types becomes rare, old programmers may still use anonymous type in Linq by habit.
There are various differences between anonymous types and C# 7 tuples, which may or may not make one more appropriate than the other in certain situations:
ValueTuple<>
s. That means they are value types while anonymous types are reference types.ItemN
(for numbersN
). The labels are just metadata information that is mostly used by the compiler, and is not persisted with the actual tuple object.(int, int)
tuple for a size would be fully compatible to an(int, int)
tuple for a position, while anonymous types are closed off completely.