Feedback on primary constructors #7667
Replies: 18 comments 64 replies
-
I'm really puzzled as to why this question is being asked. It should have been super clear to MS from feedback a month or two back that lots of developers were deeply unhappy with the way mutable "captures" were the default behaviour for non-record PCs and how any other behaviour had to be achieved via extra code and custom analyzers. We face the situation in my present company whereby the consensus in the development department is that this feature is so far removed from being "fit for purpose", we will be implementing a custom analyzer to block the use of this feature until PCs are "properly" implemented. To put it into context, we already have stories in our backlog to update our code base to C#12 and a "brown bag" session planned to show off the other new features later this month. These are developers that are normally enthusiastic about new releases. This is the first time for any C# feature, in any release, that the team has even remotely contemplated blocking it. Just get on with supporting a means of those PC parameters being "captured" via private readonly fields with the minimum code ceremony possible, as quickly as possible, please. |
Beta Was this translation helpful? Give feedback.
-
i want this: class State()
{
private readonly TreeNode<State> tree=new TreeNode<State>(this);
public State Substate => tree.Parent.Value;
} You see, the main constructor with parameters. The assignment of fields using parameters is already in the execution phase of the constructor. |
Beta Was this translation helpful? Give feedback.
-
How to invoke a method like In general, the question here is how to do something more with a PC. Similar to partial methods, define a construct that gets hooked up in the PC body during auto code gen. |
Beta Was this translation helpful? Give feedback.
-
Personally I think we should stay away from adding features to the PC (Primary Constructor) parameter list that makes little-to-no sense in any other parameter list.
Creating a public property? Does that make sense to add to any ol' parameter list? I think no. Feels out of scope. That said though; Could the syntax for props-in-PCs translate cleanly to some other tangentially related concept in method signatures? Possibly, but I can't think of any right now. I think that we should not confuse Primary Constructors with "Simplifying data-modelling" because they are tangentially related at best. |
Beta Was this translation helpful? Give feedback.
-
As mentioned in the blog, the readonly flag would be extremly usefull. But completly looses its value if Public Properties get Created. (or even blocks this feature from useage in different teams) The typical usecase is in DI. So here i do NOT want to expose the consumed services. So as feedback:
in order to be able to propperly use this feature, both of this points have to be meet. edit: i hope it is not nessecary to wait a full year until net9 to get to such an improvement! |
Beta Was this translation helpful? Give feedback.
-
Asking for three features working together: support for always-enforced construction preconditions, support for
public class Triangle(int x, int y, int z)
{
primary_ctor_body()
{
// if for any of the x, y, z the sum of the two other values is shorter or equal,
// throw an exception the triangle construction precondition / invariant was violated
// because it is not possible to create a valid triangle with these lengths.
}
}
Now, with 1. and 2. together I can construct an immutable object (due to
|
Beta Was this translation helpful? Give feedback.
-
Now anything can be initialized anywhere. Feels like C# is moving towards javascript. |
Beta Was this translation helpful? Give feedback.
-
It would be nice if the behavior of properties could be defined on the primary constructor parameters themselves as closely as possible to the normal auto-properties themselves. I mean any or all of:
Probably by reusing the relevant property syntaxes. Maybe: public class Person(
public string Name { get; private set; }
)
{ } I believe that's as far as I would go. If you would need additional possibilities, like inheritance modeling with virtual members, there's the "classic" way to define properties. Also, I believe final initializers would be nice to have.
public class Person(string name)
{
public string Name { get; set; } = name;
public override string ToString() => name; // Oooops, this should've been "Name".
} As per @CyrusNajmabadi, this seems like a non-issue. |
Beta Was this translation helpful? Give feedback.
-
I wonder if too late to suggest parameter in the PC to be public (instead of private) by default, similar to that of record type. Immutability can be enabled explicitly. |
Beta Was this translation helpful? Give feedback.
-
As I mentioned here, I'd like to be able to create a field from the constructor parameter, so that it can be accessed with
public sealed class Example(field IMediator mediator) |
Beta Was this translation helpful? Give feedback.
-
I'd like to see the I'd also like to see accessibility modifiers applied that would promote the parameter to a named member within the type. The two could be combined to promote the parameter to a public class Foo(
string foo, // regular mutable capture
readonly string bar, // readonly capture,
public string baz, // public mutable field
public readonly string qux // public readonly field
) {
// ...
} Inline declarations of properties could be interesting also, although I wonder if that's a step too far, especially as I imagine that there's a limit to how complicated a property could be. An auto-property could be palatable, but a partial auto-property or a full property? |
Beta Was this translation helpful? Give feedback.
-
For those interested by this feature, but want more control over the generated field, I've created a NuGet package which allows you to put |
Beta Was this translation helpful? Give feedback.
-
Can we have a #pragma or something, such that the fields names can get a prefix underscore? for example, Alternatively, we could declare |
Beta Was this translation helpful? Give feedback.
-
Just want to add some positive comments among all complaints. I like the feature. It reduces the ceremony for DI, and the lack of readonly isn't too big of a deal. Just don't mutate the value, and you'll be fine. I don't know if the |
Beta Was this translation helpful? Give feedback.
-
I would like to be able to affect the generated field name, i.e. to allow underscore prefixes like requested here: #7565 I know that primary constructor parameters are technically parameters and might not be kept as fields/properties but they are in the current implementation, I even found it mentioned on the MS page: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/instance-constructors#primary-constructors
I also find it confusing that primary constructors work differently for records than for (typical) classes, i.e. I cannot apply |
Beta Was this translation helpful? Give feedback.
-
This feature won't be useful for me until primary constructors can have bodies for logic (like the "do" block in F#). I am mostly stuck with normal constructors for now, but if primary constructors eventually get logic bodies, I would probably be able to replace almost all of my normal constructors with primary constructors. The syntax for primary constructors is just must nicer overall. |
Beta Was this translation helpful? Give feedback.
-
USE CASE
Two issues: (1) No body supplied for the primary constructor!!!! What genius thought this was a good idea!!! In general, this whole attempt to shoehorn a “primary constructor” into the language has not been thought through and is incomplete at best. I my opinion, new isn’t always better. In this case introducing a half-baked idea all for the sake of brevity is just plain stupid. |
Beta Was this translation helpful? Give feedback.
-
I propose the following solution for enhancing functionality within the context of PC: For backward compatibility, the constructor method should retain the same name as its containing type. Historically, nearly all access modifiers have been employed to define constructors, except for the newly introduced Thus, this new modifier can be used to define the additional method that gets invoked as part of the PC, with the invocation order determined using an attribute. public partial class MainPage(MainViewModel viewModel) : ContentPage
{
// Newly proposed method that acts like a constructor body, gets invoked in the PC
file MainPage()
{
InitializeComponent(); // UI Initialization
BindingContext = viewModel;
}
} |
Beta Was this translation helpful? Give feedback.
-
C# 12 introduces primary constructors for non-record types: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-12#primary-constructors
What else would you like to see and what are the important scenarios to you? A gesture that creates properties in non-record types? Support for immutability in primary constructor parameters? Something else?
Beta Was this translation helpful? Give feedback.
All reactions