Search code examples
c#compiler-optimizationanonymous-typesc#-7.0valuetuple

Are C# anonymous types redundant in C# 7


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?


Solution

  • 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:

    • C# 7 tuples are ValueTuple<>s. That means they are value types while anonymous types are reference types.
    • Tuples allow static typing at compile time since they are a type that can be expressed explicitly. As such, you can use them as method arguments, return types, etc.
    • Members of an anonymous type are actual properties that exist on the type. Tuple items are fields.
    • The properties of an anonymous type have an actual name, while the fields on a tuple are just named ItemN (for numbers N). The labels are just metadata information that is mostly used by the compiler, and is not persisted with the actual tuple object.
    • Because creating an anonymous type actually creates a type under the hood, you have a level of type safety with them. Since tuples are just generic containers with applied type arguments, you do not have full type safety with them. For example an (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.
    • As Jon Skeet mentioned, the C# 7 tuple syntax is currently not supported in expression trees.