Are C# anonymous types redundant in C# 7
Asked Answered
I

2

15

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?

Inquisitionist answered 30/6, 2017 at 16:23 Comment(16)
Readability perhaps? new {x, i} makes it completely clear that it is a new object that is being returned, whereas I had to compare the two examples to figure out what the first one does. But then it might just be me.Veer
For one thing, they're supported in expression trees and tuple literals aren't...Vanderpool
Note that your example wouldn't compile in C# 7.0 because (x, i) has unnamed tuple elements, but they're implicitly named in C# 7.1.Vanderpool
Anonymous types are handy for compiling old code that uses them.Kutaisi
There are objective differences between anonymous types and tuples, and there are cases where tuples objectively can't be used or will behave worse. So I think this question can be answered purely based on facts, no opinions, and shouldn't have been closed.Richly
Agree with @Richly here: closing this as opinion-based is a mistake. A good, objective answer to this question would be useful to all. Voting to re-open.Shangrila
@Richly The question isn't asking if there are objective differences between anonymous types and tuples. It asks for users' personal preferences on when they'd rather use one or the other. It's explicitly asking for opinions. Just because one person prefers one of them and not the other doesn't make it a statement of fact; it's expressing an opinion.Urology
@DavidArno The question is literally asking for people's personal preference. That's what the question is. It's physically impossible to provide an objective answer. You listing off why you prefer one over the other is you stating your personal opinion, not a statement of fact.Urology
@Servy, then edit the question to make it better. When to use tuples versus when to use anonymous types is a good question to ask, with the release of v7.Shangrila
@DavidArno No, that's asking for opinions. If you want to have an opinionated discussion over what features people like, you're more than welcome to do so, but an SO question isn't the place to have such a discussion. There are plenty of places where it is appropriate to ask for people's opinions, if that's something you're interested in doing. Since the question is inherently asking for opinions there's no way to edit the question into one appropriate for SO without fundamentally changing the entire question into something unrelated.Urology
@Servy, "Many good questions generate some degree of opinion based on expert experience". This question falls completely into that category. Thus it is incorrectly closed.Shangrila
@DavidArno No, it doesn't at all. It's asking strictly for opinions, and nothing else. If you keep going with the close reason, "but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise." That's completely true for this case. That you don't care that it's asking for opinions, and that you want to simply have a bunch of people post their opinions doesn't mean it shouldn't be closed, in fact, that's exactly why it needs to be closed. It's questions like these that are exactly why this close reason exists.Urology
@DavidArno So it's your opinion that the question isn't asking for opinions, even though it's a purely objective fact that the question is asking for opinions? That's...not how things work. You don't disagree over facts. The question is asking for people's personal preferences, rather than facts or an objectively answerable question. You can say that you don't care, and that you intend to disregard the rules entirely because you don't like them, but you can't say that a question asking for people's personal preferences isn't opinion based.Urology
@Urology Dear Servy, I do not know why this question made you so adamant to close it. Perhaps I worded it incorrectly due to some sort of a language barrier. The wording of the question is now changed to exclude the use of the word preferred, even though I originally meant it as given guidelines, such as the use of camel-case for methods. All I asked for were pros and cons of using one over the other and cases where one has to be used over the other. From your incredibly heated argument I almost feared you'd prefer to have the option to "close and set on fire" instead of just "close".Hewes
@IgorŠevo Your question wasn't unclear. It's clear what you're asking for. And what that is is people's opinions. While there are lots of places where such discussions are welcome, this isn't one of those places.Urology
shouldn't y => arr[i] be y => arr[y.i] ? Also, tuples are used when the element names are not needed (1, 'a')Armlet
W
13

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.
Witkin answered 1/7, 2017 at 15:39 Comment(5)
Nice answer. Will you include Jon Skeet's point about tuple literals not working in expression trees?Anticathode
I like the answer because it provides implementation details about ValueTuples. But it still doesn't answer the OP question: are there scenarios where anonymous type is better than ValueTuple? Point 5 (as far as I understood) is more about considering using ordinary types instead of ValueTuples.Anticathode
@VadimOvchinnikov Yes, of course there are scenarios. Those scenarios where the difference between those two features are relevant. – If you need an example, take Dapper where you can pass in an anonymous type with named query arguments. Since tuple objects have no associated name, you could not do this with them.Witkin
anonymous types are only type safe when used locally. other wise you have to treat it as dynamic object meanwhile tuples provide type safety all over the place (though regardless of item names), I don't see case where anonymous types could be effectively useful over tuples. (in single block its not hard to make sure tuples for different purposes are not mixed). tuples are much useful and anonymous types now serve as backward compatible solution.Braunschweig
the only thing that comes in place, is tuples being value type and anonymous types being reference type. there maybe cases where having reference type is essential.Braunschweig
B
1

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

  • you can not use anonymous types globally and they are only type safe when used locally. not being local you have to treat it as dynamic object which has significant performance overhead

Reasons 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, like car

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

  • Anonymous types are reference type but tuples are value type.

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

public class Point(X, Y);

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.

Braunschweig answered 24/10, 2017 at 6:23 Comment(1)
Anonymous Types and Tuples are used in different situations. For example: in LINQ you should use anonymous types and if you want to use expression trees you must use anonymous types. Expression trees are not supported by Tuples.Punchboard

© 2022 - 2024 — McMap. All rights reserved.