-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lift Object initializers to constructor role #2558
Comments
Why don't named arguments for constructors suffice here? That's likely what will be used for records, not object initializers. I don't like the idea of setting a As for a compiler flag, each one creates a dialect of the language. The bar for creating such a flag should be absurdly high. If a normal language feature needs to break 100 points, a language dialect should have to exceed a billion, in that they're only considered to solve "billion dollar mistake" caliber problems. |
I strongly disagree. Constructors are and should be used a lot more often |
Regarding constructors vs object initializers, I was in favor of constructors, with named parameters when needed. My own proposal #1614 is based on the merits of constructors. But without any primary constructors in C#(unlike Kotlin), naming style deference between (constructor) parameters and properties, constructors are more of a chore, specially for DTO or data classes. Object initializers are more flexible. That's why object initializers are often used. That's why language designers and library writers tries to keep the provision of using objects initializers for data classes. EF core is doing that for models. I don't the future, but all the previous discussion regarding record tried to keep the option of using object initializers. One proposal was only supporting object initializers. Some proposals were there to support initializers with some magic (mutable nullable builder classes), which will still change the definition of object initialization in some way. And developers have to keep that thing in mind. Regarding compiler flag, I admit that adding a compiler flag is like introducing a dialect of the language. I don't want a separate dialect of C# based on just this feature. What I want is, include this feature in the "Nullable reference type" dialect. May the name of the compiler flag/ dialect be changed to something like "safe" or "strict" for clarity. One may argue that although this feature looks like object initializers, but it is something else(a real constructor with the ability to initialize |
Why can't you just use a static function which accepts your type and then encapsulate that through the use of an Action? I don't see why the entire language needs to support a feature just so you can Memorize if you have initialized a type or not? If the readonly is assigned in the constructor that you can call an arbitrary init method from there anyway. IMHO this is much more a matter of library design than that of a language feature which is needed. |
Object initializers are quite popular and arguably the default way of constructing/initializing objects in C#. I am proposing here to lift their role to constructor level. Which means object initializers will be able to set properties, which are otherwise only settable in constructors. Some arguments for it-
Modern programming languages usually facilitate and even encourage two things- Immutability and Non-nullability(or expressing and tracking absence of values). C# has long supported getter-only properties and
readonly
type members supporting immutability. And non-nullability support was there for value types and coming for reference types. But Object initializers do not play nice with them. If lifted to constructor level, immutability and non-nullability will become more common without awkward code-circus. This will result in safer code.Being a popular way and arguably default way to initialize objects (specially data objects), object initializers deserve to be a core language feature rather than being a syntactic sugar like it is now.
If records ever come to C#, most probably this is going to happen one way or another, at least for the records.
Now the question is, isn't this a breaking change? Of course, internally it changes the meaning and implementation of the construct. But on the surface it still carries the same meaning- initializing an object. In exiting usages, it will keep doing what developer intended it to do. But it will enable new scenarios. Currently I cannot think of any situation where this breaks current code- generate errors/warnings or working against the intent of developer. Please discuss if you can find one.
Still I think, there should not be a silent behavior change and this should be enabled under a flag. And compiler should keep supporting both meanings of object initializers for some time at least. But I think, rather than having its own flag, this can be tagged with "Nullable reference type" compiler flag- same flags enabling both features. One reason for this is, the shortcomings of object initializers become more visible with nullability tracking. Also enabling two features together can facilitate warnings on not initializing non-nullable readonly properties.
Any thoughts?
The text was updated successfully, but these errors were encountered: