[Proposal] Inline records #2750
Replies: 9 comments
-
The scope of something declared within a method should be that method. Target typing the fields of a declared type will also inevitably lead to very fragile types. A tiny change that affects the expression can redefine the fields of that type causing a cascade of changes. Structure should be explicit. |
Beta Was this translation helpful? Give feedback.
-
You can't define classes inside methods, so, it is OK to expected them outside them. This is a new thing with new roles.
This is the same case with anonymous types and tuples. There are situations when you declare the class just to fit the data you want to bass from a controller to a view or to load some values, or return them. The expected changes are the reason that we need these classes to be auto generated to fit the data. This is some sort of dynamic object but strongly typed and has a name to allow passing it through parameters. This is a general solution for many issues I published before. |
Beta Was this translation helpful? Give feedback.
-
As an aside, this is really bad for incremental compilation, since you now need to bind all method bodies to provide intellisense. The performance impact of this may well be huge, and it would have to proven that this is not the case before any such feature as this could be accepted. |
Beta Was this translation helpful? Give feedback.
-
@YairHalberstadt |
Beta Was this translation helpful? Give feedback.
-
A possible solution is to define these inline records outside methods. C# can still use type inference inside these types as it does in tuples and anonymous types. |
Beta Was this translation helpful? Give feedback.
-
You can define local functions within methods, and they are limited in scope to that method. The team has expressed interest in local types as well, with similar scoping.
It's not the same because neither create a new type that is promoted to the public surface. The scoping of the structure of an anonymous type is similarly to the method in which it is defined. You can upcast and pass it as an Also, as you stated, you want these constructs to be mutable, but that runs counter to anonymous types, on which this syntax is based, and with records. Identity, which is a property of records, can't be established (safely) with mutability. |
Beta Was this translation helpful? Give feedback.
-
@HaloFour |
Beta Was this translation helpful? Give feedback.
-
If something like that happens at all it would be through source generators, possibly like this: [JsonClass("settings.json")]
public partial class Data { } In which case you can have your generator code emit whatever source you want. |
Beta Was this translation helpful? Give feedback.
-
I quite like this idea, but more for method parameters. I wish this initial proposal were updated to make this the primary use case. When working with restrictive APIs like ASP.NET Core MVC that require [FromBody] attribute on only one parameter. A common workaround today is to use inline tuples as parameters. It only makes sense that inline records would be supported, too! Possible Today[Post]
public ActionResult PostData([FromBody] (int Bar, int Baz) data)
{
var (Bar, Baz) = (data.Bar, data.Baz); // unwrap
}
Not Possible Today but Desired[Post]
public ActionResult PostData(record Foo(int Bar, int Baz))
Alternatives ConsideredI could use Source Generators that "thunk" all ASP.NET Core Attributes to create a tuple unwrapping layer automatically for any action that has multiple parameters. I don't really like how this reads though and seems like a Frankenstein. Sometimes the best features are "to have not at all". |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I propose to allow us to define data driven records like this:
Syntax:
Implementation:
This code will generate the following types:
Note: it will be better to use Records to implement this, once they are launched, but I prefer normal classes if Record will be immutable, so we can have alternative way to define mutable records. You may add default constructors and deconstructors to the implementation.
and the original code will be lowered to:
Benefits:
Beta Was this translation helpful? Give feedback.
All reactions