[Proposal] allow use anonymous type out local scope #3962
Replies: 2 comments 8 replies
-
If you have to fully declare the shape of the anonymous type in the signature of the member exposing it why does it provide any benefits over just using a record? The only difference becomes the fact that you have to name the type, which is certainly preferable anyway as the type name is as critical as any of its members and if it changes, even unexpectedly, that will break any existing assemblies that happens to consume that type. As name generation impacts the public surface of the assembly that forces the exact details to have to be a part of the language specification, which will undoubtedly be non-trivial. Personally, I find the following much better, and something you can use now: { string Name, int Age } GetPerson() => new { Name = "John", Age = 24 };
// vs
record Person(string Name, string Age);
Person GetPerson() => new("John", 24); The team has further expressed interest in making anonymous types into records, as well as enabled value type records and reducing the amount of code necessary to write nominal records. |
Beta Was this translation helpful? Give feedback.
-
The problem here is if you want to cross assembly boundaries. When you declare an anonymous type, the compiler emits a new type into that same assembly. If two assemblies define anonymous types with the same members, the compiler will emit separate definitions into each one. If you allow anonymous type instances to cross assembly boundaries, you've got a problem: although both assemblies might be using anonymous types which look the same, in fact underneath they're distinct, unrelated types. The runtime doesn't let you do assignment between such types. This problem is exactly the one the LDM faced when designing ValueTuples, and the reason that ValueTuple is defined in a central assembly with the members Item1, Item2, etc, and then compiler magic is used to give the members actual names at compile-time. So long as anonymous types can't escape method bodies, they can't cross assembly boundaries, so everything is fine. Remove that limitation and you've got problems. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
anonymous type and tuples have a lot in common: both are used to glue values without the need to declare a new class/struct.
we could allow the use of anonymous type out of the scope where it was defined by using the same way syntax that tuples, just using curly brackets instead of parentheses (when explict type declaration).
currently tuple support:
proposal anonymous type support:
Since the usability and functionality is practically the same, what is the point of this proposal?
Although, both types have much in common, there are several factors which developers must consider when choose between both. Some relevant points:
Although there are cases where anonymous type is more appropriate, we are currently limited to local use. Removing this limitation we would be able to take much more advantage of anonymous types, which is an amazing feature.
The idea it is to create a alternative that allow you mix the benefits of tuples (anonymous group of data) as well the benefits of records (immutable, element names in runtime, serialization, etc).
Note that this feature practically allow anonymous types to act like anonymous record types, as they have the rest of the properties of a record already: value equality, ToString, etc.
Combined with #3530, anonymous types would become even more convenient to use.
Just out of curiosity, after research I found that F# already have anonymous record types.
EDIT:
Currently anonymous types are implemented as
internal sealed classe
s. This proposal does not include change it.So anonymous type would be allowed to be used as members, but limited to internal assembly usage, otherwise compiler would emit the error CS0053 (Inconsistent accessibility: type '{ string Name, int Age }' is less accessible than property/field/method ....) when try to expose the type. That is, the same currently rules for types with
internal
accessibility.Beta Was this translation helpful? Give feedback.
All reactions