Proposal: Beyond property initialization to code block initialization #5808
Replies: 8 comments
-
@softwaremills C# has the concept of object initializers, maybe this concept can be expanded. So it would be something like this:
|
Beta Was this translation helpful? Give feedback.
-
@eyalsk That might get most of the way there. I like having the named reference to be able to have the full capability of blocks, like being able to, say, pass the For instance, here's an actual snippet from my codebase:
|
Beta Was this translation helpful? Give feedback.
-
with-expressions in https://github.com/dotnet/csharplang/blob/658e65403a9e14d9f614994d1fd6757d4fab9608/proposals/records.md |
Beta Was this translation helpful? Give feedback.
-
@ufcpp That is a good point; any proposed changes would need to be compatible with the syntax in records and, in particular, the with-expressions you mention. Good call. This is quite different than records, of course, which are meant to enable good practices in immutable structs. This proposal is meant to refer to taking any expression, providing a block that operates on that expression, with the whole thing evaluating to the original expression. The syntax would ideally be general-purpose syntax that would be very useful for building complex literals. Such things happen a lot in the creation of data structures to be serialized (as in my code snippet above) or, possibly, applied to user interfaces (say, for instance, the creation of React-like virtual stand-in elements). |
Beta Was this translation helpful? Give feedback.
-
Kotlin supports a similar construct, and has the automatic "it" variable in the callers' context for such closures. I use such a extension for years, but naming it apply, config, utilize .... The mechanism is also very useful as constructor and could replace the object initializer with the advantage to access the methods also. ` class XY
} |
Beta Was this translation helpful? Give feedback.
-
There was extensive discussion just about such a request raised by @najak3d in #5728. I'm also interested in the performance penalty of using these simple lambda callbacks in a method like |
Beta Was this translation helpful? Give feedback.
-
I like your proposes "with" syntax. This seems intuitive and effective to me: var views = new[]
{
new View(context) with v { v.SetBackgroundColor(color1); },
new View(context) with v { v.SetBackgroundColor(color2); },
new ViewGroup(context) with vg
{
vg.AddView(new View(context) with v { v.SetBackgroundColor(color1); });
vg.AddView(new View(context) with v { v.SetBackgroundColor(color2); });
},
}; If this my proposal #5728 were approved, it would handle your notation for this example like this: var views = new[]
{
new View(context) { .SetBackgroundColor(color1) },
new View(context) { .SetBackgroundColor(color2) },
new ViewGroup(context)
{
.AddView(new View(context) { .SetBackgroundColor(color1) }),
.AddView(new View(context) { .SetBackgroundColor(color2) })
},
}; But my proposal would not handle the more complex logic that you sometimes run now (e.g. with "if" statements, etc). For those, you'd still need your "with" syntax (or continued use of an Extension method). |
Beta Was this translation helpful? Give feedback.
-
Hi all, I wanted to engage with this great proposal and suggest a possible extension to the idea of object initializer blocks. While the current proposal moves us closer to simplifying object creation and initialization, there's a key use case it doesn't fully handle: executing additional actions based on whether an object is newly created or reused. This can be addressed more elegantly with the introduction of Object Statement Blocks. Key Proposal would be for an Object Statement Block syntax that allows not only property assignments but also method calls and conditional logic. This enhancement would enable the use of object.{} syntax on any object, improving flexibility and readability in code. Here's how it would look:
Mixing with Object Initializers:
Additionally you could use encapsulation and do this: This encapsulation would allow the code block to be applied to either the existing or the new object, resulting in a significantly cleaner syntax. Looking forward to your thoughts! |
Beta Was this translation helpful? Give feedback.
-
I have found this to be a really useful function:
I generally use it when I want to do some initialization without assigning a variable, and that initialization doesn't come in the form of setting a property:
That does work, but it annoys me that it's setting up a bunch of closure objects and functions behind the scenes for something that should be pretty simple syntactic sugar. Of course, not being a language designer, I have no idea what the proper syntax should be for this sort of thing. I imagine something like this:
I mean, I use my little helper
With()
in places, but I still cringe. And I find this pattern so useful all over the place, especially where you're building some complex data structure and it's not sufficient to use property initialization or collection initialization.Beta Was this translation helpful? Give feedback.
All reactions