C# 7.0 ValueTuples vs Anonymous Types
Asked Answered
G

2

33

Looking at the new C# 7.0 ValueTuples, I am wondering if they will completely replace Anonymous Types. I understand that ValueTuples are structs and therefore behave a bit differently than Anonymous Types which are classes. I don't see a use-case, however, in which I would prefer using an Anonymous Type over a ValueTuple.

Are there any use-cases where using an Anonymous Type would still be beneficial over using ValueTuples in C# 7.0?

Gnawing answered 15/12, 2016 at 13:9 Comment(0)
B
27

Anonymous types are immutable, ValueTuples are not. This is reflected in the fact that anonymous types expose properties, ValueTuples expose fields. Data binding almost always requires properties.

Plenty of existing code only works with reference types, not with value types. What in particular comes to mind are projections in Entity Framework: projections to value types are simply not implemented.

Bingle answered 15/12, 2016 at 13:25 Comment(0)
A
10
  • anonymous types can carry name data inwards, but cannot express name data on signatures
  • value tuples can express name data on signatures, but cannot carry name data inwards

Signature example:

(int Id, string Name) GetFoo(...) // could also use tuples in args, but not very useful

There is no way of doing this with anonymous types, as you cannot express the anonymous type other than as object on a signature.

"Inwards" example:

by this, I mean passing name data into libraries. For example, if we consider JSON:

var json = SomeJsonConvertAPI(new { Id = 42, Name = "abc" });

the library will be able to see the names Id and Name, and work accordingly (coming up with JSON like {"Id":42,"Name":"abc"}); however, this is not possible with value-tuples - any library, whether using <T> or object or something else, will only see the Item1, Item2, etc - with no mechanism to obtain the name data that exists at the originating site.

What would be nice would be something that is similarly terse to value-tuples and anonymous types, but which can be used in signatures and to pass inwards into libraries; and thus C# 9 gives you records:

record Foo(int Id, string Name);

which is short-hand for a class Foo with members int Id {get;} and string Name {get;} with all the constructor and equality bits you would expect.

Aleydis answered 10/8, 2020 at 13:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.