For those wondering, yes the required keyword IS coming in C# 11. It was demoed at Build and NDC Copenhagen and I confirmed it with Mads Torgersen himself
@@DavidBondOnline that would likely be up the deserializer - it emits an attribute, which the compiler enforces at compile-time, but things like serializers, validators, mappers and DI containers will likely need to use reflection and respect this new attribute. So not a simple, ideal solution in that way - but it's too late for that, I guess. Established languages don't really make breaking changes, and the VM and run-times already support multiple languages - as with most popular software, complexity can only really go up from here. What makes this worth while, is the it lets you remove complexity from your code.
I was waiting a long time for this feature. I was really upset that it was removed from C# 10 release. As I said in the comments under one of the videos, required keyword is one of the most awaited thing for me in C# 11. I use nullable enabled a lot in my projects so required keyword will be the last thing I am missing to make my code safer and cleaner
I agree, I've been using constructors this entire time to ensure they are properly not null when using nullable it has lead to a way messier codebase than I would have liked
"Attribute constructor" means you could write something like [Required(FullName="Nick")] - because as you saw it's implemented with an Attribute. I haven't tested it though, and I'm not quite sure how that would make sense... unless it acts as a default value? (Or the error message needs some love.)
This feature should have been added when the Explicit Nullablity was added, I would have spent less time having to argue why setting a non-nullable string property value to null using null-forgiveness or empty string is not a good idea on models that have many of these properties that it would create an unwieldly large ctor. The more I see of 11 the more I look forward to its arrival.
Can you please elaborate on this, as I am not sure I understand. Let's say you have 10 "required" properties and you create a 10 parameter constructor for that. If you initialized the object the old way, you would have to pass 10 arguments in there. But if you use the required keyword, you still have to provide those 10 values, no? So how does this or Explicit Nullability make it less unwieldy?
Oh wow, finally, this is the most necessary feature i have been waiting for in my use case. This makes Initialization so much cleaner and improves on the nullable scheme C# has been moving towards. This removes so much unnecessary boilerplate code in my codebase that is only useful for making the compiler shut up about warnings, without any additional benefit.
@@IIARROWS yes, but i have a personal policy on my code that i keep nullable on to write more safe code. I think nullable is a great addition and instead of circumventing warnings, we should introduce semantics that do not raise such warnings. This is why i like this new feature
@@IIARROWS well in fact it can be null. If you mess up and forget to provide the property. That's why I think = default! (except for injected values) or turning off NRT is a bad idea. Just create a constructor for required properties. With named parameters it almost looks like property initialization. That being said the required keyword is better and I will replace my constructors with it.
I really like that they're adding more tools for api/tool code to demand correct usage through compiler errors rather than runtime errors, that's the most powerful thing a compiled language can do to help us
This is great in theory, but only for simple constructors. Any time you have to initialize a collection property with an empty List, you’ll be right back to doing it the old way.
I just hope this works well with JSON serialization. That requires a parameterless constructor for deserialization anyways most of the time, so the required keyboard spares me a lot of checking code. I appreciate it immensely. And I also also highly appreciate the work you're doing with Videos and courses.
Any updates on this? I remember using deserialization skipped a lot of the initialization rules we had in the past, such as defaulting a property to an empty collection, both in the constructor or as a default property assignment. C# basically just created an object from what it was given and ran nothing else, so it always made sense for us to just have a validation service that would run. Or in this case, "correct" the data. Treating it like a DTO and then mapping to a full fledged object probably would have been the better choice, but live and learn when maintaining feature parity across multiple code bases simultaneously lol.
This helps patch the huge hole created with non-nullable types on properties. Now you won't be able to forget to initialize those important properties. Constructors were sometimes an option but often felt too clunky to use. I'm so glad this feature is finally coming to c#.
what if i need to run a class method to initialize a property? i would normally run it in the constructor and assign its return value to the property but like this, without a constructor, i'd have to delegate that to an external method in order to call it during initialization. maybe this will come in handy for a few scenario but constructors will still be needed for complex inits
I felt it when you showed the constructor where each line had a value to pass in required fields. I’ve been in that scenario far too many times. I was also in a bit of a pickle because the settings for our quality gate, SonarCloud, restricted the number or arguments for methods including constructors. So in the end I ended up resorting to “smuggling” arguments in a class solely built for passing all the arguments I needed. I do like the idea of transforming object initializers into de facto customizable constructors with the ability to declare required properties. I’ve been out of the loop for a while due to health issues so I’ve been enjoying catching up watching Nick. Thanks Nick!
I’m curious to see if classes with the [RequiredMember] attribute will impact Activator.CreateInstance()… mainly from the perspective of a library/framework maintainer…
I haven't read through the proposal or related media, but based on what I saw here it looks like it's something that only happens at compile time for statically known things, which Activator and co. already don't care about. I imagine this changes nothing since the default constructor should still exist, but I can see a world where they throw an exception I guess.
Seems almost like a constructor with braces instead of parentheses. Defining by marking the properties themselves as required is nicer than defining the same concept in a constructor. But it is basically the same thing.
My only issue is if some property is partially required. For example if another property is set like if MiddleName is set then FirstName is required. This should probably be solved by an abstract factory but constructors would also be a solution aka having Person(string first) { } Person(string first, string middle) { } Person(string first, string middle, string last) { }. However it would be good to put required on the first name.
This looks very nice, but i have a big problem with this feature. You cannot do any validation based on the member. A sample would be: You have the properties Start and End and want to validate that Start is smaller than end. How can you handle it with this feature? Constructor is called before any value is set and if you do the logic in the properties the order matters. PS: Sorry for my bad english
I love it. I have hated constructors for dto unless you go the full record route. And doing nullable makes it more difficult because you have to assign fake values everywhere. Now you can just require and not deal with string.empty everywhere. Thank you as always
that feature comes from dart, dart is the language of flutter, in dart you may declare a variable as required on the constructor then you must provide a initial value or the compiler throw a error
With the 'required' keyword on the horizon, it feels like C# is finally turning up the volume on its safety feature. Forget constructors, it's all about concise and clean code now. It's like spring cleaning, but for our codebase!
I kind of take the opposite view: Where initializers exist, they're evidence of a deficiency in the provided constructor(s) on the class. If you have to assign 10 properties to the object to initialize it correctly, the problem isn't that you have a really big constructor; it's that you have a God Object that needs massive amounts of initialization to work correctly.
Great video as always! I'm wondering if DI containers will support the required keyword. As far as I know, all of them rely on constructors for automatically determining which dependencies should be injected.
I don't think they will because I don't think it will solve the same problem. The main reason why required makes sense for POCOs (mostly) is that you actually initialize them yourself. For classes with injected dependencies, you never initialize them explicitly (except for unit testing when you pass the mocks)
Hey Nick, I would love to see an ASP Net Core class that ignores MVC and focuses purely on the API side using best practices such as mediator and any other libraries you reccomend. If one already exists usisng C# 10 it would be great to hear your reccomendation. All of the tutorials I find focus on MVC and not the API / server side of things. This is interesting for me as I mostly use Blazor WASM as a front end and having a rock solid server side deployment would help make my application enterprise ready.
That's a nice feature. The more boilerplate unnecessary code they can remove, the better c#/.Net coding experience gets. I'd love to get rid of constructors just for dependency injection as well. Just add a "injected" keyword instead
@@petrusion2827 It's when you know for absolute certain that a property isn't nullable (using NRTs) but you need to suppress the nullability warnings of C#.It's usually when a field is init only but you don't want to make a constructor to suppress it. It's pretty standard and even Microsoft code uses it, even though I think they do "= default!" not "null!"
@@nickchapsas I'm having some trouble wrapping my head around this. Without the required keyword, aren't you risking that the caller won't initialize the property, making it null?
@@petrusion2827 There is a slight risk. In my case those properties are DTOs only used to receive json api requests, and we already have validations that return 4xx responses if thoses properties are not populated.
Are you able to "initialize" the required FullName with null or string.Empty? I'm likely to stick with constructors. It is rare to have more than a few parameters, and it is the perfect place to verify values.
I would argue it is a bad place to verify the values actually. Should it really be the responsibility of the class itself to know what values are valid? For all the types of models? Both API contracts, Domain object and database DTOs? I'd rather have a centralised piece of code that validates instead of spreading my validation integrity which can lead to problems.
@@nickchapsas Well, taking something from DDD, you can use a Value Object for FullName and I'd say it's totally its responsibility to check valid values for its invariants like don't accept empty strings or null as internal values. Then the Person class should just validate against null FullName values, otherwise, I'd say you're having a kind of anemic domain model.
If you combine it with the field keyword (please tell me it will be in C# 11), you could do your checks in the setter before assigning the value in the backing field.
@@nickchapsas Yes - it is the class's responsibility to verify it's own data integrity. Who else knows better? Granted, a class might consult global and/or injected values to decide what values are valid, but that logic is the responsibility of the class. The old-fashioned term for this is "encapsulation". I am indeed old-fashioned - I started learning C# in 2002, and was a C++ & Turbo Pascal programmer since 1988. So I humbly admit I may just be howling at the moon of modernity.
This is great and I look forward to the required keyword, but at the same time, it shouldn't be required if the language was properly designed because we already have nullable and non-nullable data types, so it should already know that the property is required if it is not nullable, but I guess this is because of backwards compatibility.
Thank you! I would definitely use this. I have needed it for at long time. Also, if you need a xaml control that needed some startup properties, you can't use a constructor for that. As far as I know, there is not "logic" way of making it obvious for the user of your control, which fields are neccessary and which are not. I hope they will make this work with the xaml compiler, so it gets angry if the required fields are not set inside the control element, or at least an option to make it so.
Hrm. I guess that's good if you don't do any validation of constructor params. What about initializing the instance with a string.Empty or " " (Whitespace) for FullName property? Can we do validation and throw InvalidArgumentException with required/init?
The benefit of having constructors is it makes your classes neater IMO. The logic for setting a properties of a class should be within the class itself otherwise you end up having instanciations of your object all over the project. It also makes it easier to read what's implementing that object when using the "2 references" (visual studio enterprise)
The required keyword on it's own is not meant to replace any meaningful "logic" that would usually be found in a constructor. Instead it is replacing the unnecessary legwork of having to create huge unwieldy constructors which do nothing but take a bunch of mandatory parameters and assign them to properties/fields. If you want to implement custom logic during initialization you can still use constructors as before for those properties/fields that need it and use the required keyword for all other mandatory ones. Same as you would use auto properties to simplify get/set access to a single line and only implement custom get/set logic as needed. Also another neat C#11 feature which Nick has not mentioned goes very well with this: You get field access in auto properties: Each accessor in an auto property will be able to implement themselves and can *refer* *to* *the* *automatically* *allocated* *backing* *field* with the fittingly named keyword *"field".* Example: public required string FirstName { get; init => field = value.Trim() }
OFF TOPIC Question > What extension, besides Sonarlint, is good for Visual Studio, in order to check Debt Metrics, Code Complexity, etc.? Something like Stepsize Debt Metrics for VS Code...
One of my main problems with records is actually that they don't have the pretty class init syntax. I think It is way more readable than using constructor when initting records (even though you can use named parameters). Very excited for this feature to land!
It's more verbose, but you can declare records and just not provide the parameter list. You'd be writing the same { get; init; } properties manually instead, but you get the initializer syntax back. For more complicated records this is what I currently do because the benefit of compiler generated Equals/HashCode is sometimes worth it, just missing the required marker still : (
Even though this wouldn’t be used for DI, it still gave me a feeling that DI could be trimmed down substantially with a similar approach. We’re almost always doing the same boilerplating in DI (except for e.g. the Options pattern), so reducing it all down to the field with a keyword such as ”inject” or something would make the code a lot more beautiful and completely remove the need for constructors in most cases!
Almost all DI already have this autowire properties functionality. But ctors are better. From point of view autofac is number one especially with optional injections, factory injections etc
@@ztBlackGad Mind you, I wouldn't mind some sort of attribute or something to mark a private field as an injected field as mentioned by others in the comments. DI can get really heavy on the constructor - too much boilerplate that is unnecessary and not that hard to fix if Microsoft/3rd parties wanted to fix it at the compiler/library level.
Sounds interesting, but we can't say that we won't need constructors. What if I want to encapsulate properties or class members? If I do with this approach, class inner fields must be an ''public', which brakes an Encapsulation approach, because members are visible outside of class. So, in my opinion right place to use it is DTO classes where we need to be initialized their members when we're creating its object. Thanks ;)
Is this feature compatible with the ASP NET Core dependency injector in the sense that we would no longer need to initialize the dependency fields/properties inside the service class constructor, or am I getting it wrong?
This isn't really applicable to DI because with DI you never had to manually provide those values in the ctor. It's done automatically by the IoC container.
Cool, something that I could never do before is now actually possible :). I wrote my own DI Container long time ago that uses MEF-like attributes and field-injection and I got massive problems with nullable-reference types. BTW, I love attributes because they tell me exactly how a class plays a role in the infrastructure in comparison to other DI DI containers where I have no clue whether the class should be manually instantiated or retrieved from DI container, I imidiatelly see what dependencies a class has, I don't need to use constructor and extra code to set the fields, and I don't need to register each class. For instance: [Export] public class C { [Import] private D dependency; } I got warnings that property is not nullable but is also not initialized directly in code. I don't want it to be nullable because it is not optional and DI container will throw an error while bootstrapping the application if dependency is missing. Using "required" keyword could solve this big problem. [Export] public class C { [Import] private required D dependency { get; init; } } I would have to use private properties instead, but it's fine and not much more code to write. But I need to experiment with the feature if it would actually work.
Does that mean that safe generic object creation will be possible, i.e. the following will be possible and compiler enforced if IFoo has required property Bar? public TFoo CreateFoo() where TFoo : new(), IFoo => new TFoo { Bar = "Baz" };
Well, with constructor you can do this: new(arg1: value1, arg2: value2, ...); you can omit the name, you can still have argument names; others have raised interesting questions, for example how does this work with reflection. To me, using an explicit constructor would be better, also esthetically it would be practically the same as new Class { args = blah }; we'll see i guess.
Builders are hard when you need to do programmatic stuff with that type, for example writing a serializer. I like it being an option but not the only way unless there is a very specific reason, for example guided initialization
Not gonna lie, this seems really strange to me, I would question why do this when records were just created which still forces that limiting by constructor approch. I'd rather have seen a 'auto generate constructor' rather than having required property construction. Seems like a split path just to try and please everyone.
So... What if the constructor contains some precalculation logic? For example, do we want to evaluate a regular expression pattern before instantiating a class?
Great news! That's one of the reasons I was so upset about using nullability features in C#. They forced me to use constructors to init properties. And I don't make use of constructors for most of my programming thigns.
Constructors already allowed for named parameters to be given. As far as I can tell the only change here is now that you can write exactly the same syntax but with curly braces instead of parentheses?
hello Nick awesome content, I just bought your class about testing (used the code and still worked, yaay!), looking forward to watch it, what I would like to see more is some high performance optimizations, usage of spans, seems like C#11 is moving in that direction with utf support and patter matching, do you think Span will be for mainstream use and proliferate thru most modern c# codebases? Can you consider making course going in depth on this topic - performance, memory allocation and usage of span and memory?
I'm torn on this feature. It's definitely good for readability of the code, especially outside of IDE (Pull Requests/Github etc), where you don't see what each constructor parameter actually is. But for developer experience while writing the code I see issues. This is nice for a model with 2 properties. Model with dozen(s) properties will be much harder to use with this feature, simply because devs will now have to discover which properties are required and must be set. Before that'd be solved with constructor that provides structured way of showing which parameters are required and which are optional. Also I've been switching to using records for any POCO/DTO type classes anyway, and those have the opposite approach with being set via the constructors. SO I dunno, I feel like this feature is, for now, tact on and sort of starts to interfere with other features they've been introducing. It will also largly depend on good IDE support to help with required property discovery. I'll see how it's handling in "real world" while it's released and what scenarios it becomes better than records, for example. Maybe IOptions, that do not support constructor parameter values injection? Dunno, we'll see.
This works very similar to the new features in PHP 8? Out of interest as a c# noob does c# support named function arguments ? Like in PHP 8 it solves the issue in my opinion of constructors with lots of arguments.
I'd say: really neat for data classes but I wouldn't use this for anything that requires DI. Say you need to register to an event on your dependency then this would now need to happen in the property setter. And I'd rather have all my initialization logic for a class in one neat place. Also if you ever needed two of your dependencies for some initialization call you'd suddenly have an invisible required order of how your properties need to be set because otherwise the code breaks. And the bad part about it is of course that that requirement can happen down the line and then your only sensible approach to that would of course be to go back to having a constructor. But at that point that would be a breaking change (granted the Di-container really shouldn't care about that breaking change but all your unit tests will mind very much so it's still quite a hassle) So tl;dr; will use that for POCOs but not for anything with logic.
@@nickchapsas Then this feature looks very useful, I can combine it for compile time validation and later reflection based validation of busines logic entities after json deserialization.
This great especially when doing refactoring. However multiple overloads was used to have some different options and flow, but given from the example using model I can see many reasons why.
Does it handle Guards, even if the string is required you could put it as an empty string right? Else I'm still stuck with constructors or static factories for my domain objects.
It wouldn't but it's not for that usecase. In DI it's not a problem because you don't manually use the constructor, it is done for you by the ioc container
While I like the idea of the feature, it takes away the ability to explicitly know how to create a class without dealing with errors. Having the values in the constructor at least tells you right away what is required to make the class. This feature you won't know, until you see errors.
I'm sure they'll have that as well; however, how does that help when looking at documentation of a library? Now you not only have to look at constructors but the properties as well just to figure out how to instantiate it. I just fail to see how this speeds up development.
Agree, and what about polymorpishm, multiple constructors with different required parameters. This is ugly way. I can not imagine big app written with this way. Huh
@@jakubhantak1960 actually having multiple constructors that initialize different sets of properties is a code smell and this pretty much eliminates that code smell, so it's a win.
I’m a bit confused. I don’t have that much experience with .NET and c# but how is this different from adding required data annotation, isn’t that the same or is that just for validation?
This is OK for POCO classes, but what if I don't want string property to have empty string, or I need to perform some specific domain validation. So in the end ctors or static factory methods are still way to go.
This functionality was really lacking before, but the option when the initialized object has fields in the constructor and required fields does not look very good 😅
I would love to have this. I only wish I could dind a migration path from Framework, which doesn’t and won’t support modern C#. This is mainly a question of updating UI from WPF.
This seems like a lowering change, which means it's supported in .Net Framework. Most language changes are supported on Framework. I only know of two things that aren't (I'm sure there are others): Default Interface Implementations, and the `with` keyword for structs. Every other thing I've tried (up to and including C# 10) works on .Net Framework 4.8
An old school approach to eliminating noisy constructors has been passing in a single class to the constructor that contained all the initial property values. I do like learning new ways to accomplish a problem. Where I work I am forced to work in .net 2.0 for the systems I work on.
Having a constructor with a long list of inputs is a design smell anyway, so it's probably better that data is being passed around in smaller classes anyway
Hmm, I don't know... at the end of the day you gotta write this down anyway AND you have extra keyword to learn. But I guess nothing beats adding the 'nullable' feature: you code it like a pointer but it has a fragment of the functionality.
This works with the nullable feature. In fact it is what makes it actually work instead of having to fake suppress warning withs "= default!" and "= null!"
You can... when you mark the property 'set'. Then you are allowed to set/change it whenever. But lets not forget that this is kind of the whole point of the 'init' keyword in the property. By marking it as such you essentially say the only time you can set it is when you create an instance and never after. the 'set' can, depending on your class/code of course, be a real nightmare as 'set' implies that the value could all of a sudden change during the lifetime of the instance. You have to add boiler plate code like checks etc. So in order to make sure people can only set a value during instantiation AND are forced to do so... is what the 'required' keyword here does.
I imagine that the check is on the codeDom side or at least at compile time What happends if you instanciate a person at runtime like this : var person = (Person)typeof(Person).GetConstructor(new Type[] { }).Invoke(new object[] { });
For those wondering, yes the required keyword IS coming in C# 11. It was demoed at Build and NDC Copenhagen and I confirmed it with Mads Torgersen himself
would you be able to use it to write api's? API should be simple.
This is great news! Will it play nicely with deserialization, I wonder?
YES! FINALLY! 😄
No more boilerplate constructors duplicating every name and type of every property. Sheesh! We needed this 😅
@@DavidBondOnline that would likely be up the deserializer - it emits an attribute, which the compiler enforces at compile-time, but things like serializers, validators, mappers and DI containers will likely need to use reflection and respect this new attribute. So not a simple, ideal solution in that way - but it's too late for that, I guess. Established languages don't really make breaking changes, and the VM and run-times already support multiple languages - as with most popular software, complexity can only really go up from here. What makes this worth while, is the it lets you remove complexity from your code.
Look like it's not coming in C# 11. At least it's not mentioned in the release notes and the tracking issue is still open.
I was waiting a long time for this feature. I was really upset that it was removed from C# 10 release. As I said in the comments under one of the videos, required keyword is one of the most awaited thing for me in C# 11. I use nullable enabled a lot in my projects so required keyword will be the last thing I am missing to make my code safer and cleaner
I agree, I've been using constructors this entire time to ensure they are properly not null when using nullable it has lead to a way messier codebase than I would have liked
Was going to comment something very similar. Very nice that it's finally coming!
"Attribute constructor" means you could write something like [Required(FullName="Nick")] - because as you saw it's implemented with an Attribute. I haven't tested it though, and I'm not quite sure how that would make sense... unless it acts as a default value? (Or the error message needs some love.)
@@BadgersEscape I do that, makes my code look very enterprise/shitty
This feature should have been added when the Explicit Nullablity was added, I would have spent less time having to argue why setting a non-nullable string property value to null using null-forgiveness or empty string is not a good idea on models that have many of these properties that it would create an unwieldly large ctor. The more I see of 11 the more I look forward to its arrival.
Yeah I had to basically "lie" in my code and add all those "= default!" or "= null!" calls that are error prone. Finally I can remove them
Can you please elaborate on this, as I am not sure I understand. Let's say you have 10 "required" properties and you create a 10 parameter constructor for that. If you initialized the object the old way, you would have to pass 10 arguments in there. But if you use the required keyword, you still have to provide those 10 values, no? So how does this or Explicit Nullability make it less unwieldy?
Oh wow, finally, this is the most necessary feature i have been waiting for in my use case. This makes Initialization so much cleaner and improves on the nullable scheme C# has been moving towards. This removes so much unnecessary boilerplate code in my codebase that is only useful for making the compiler shut up about warnings, without any additional benefit.
You can finally say goodbye to those "= default!" calls. it also makes working with deserializer code so much easier
@@IIARROWS yes, but i have a personal policy on my code that i keep nullable on to write more safe code. I think nullable is a great addition and instead of circumventing warnings, we should introduce semantics that do not raise such warnings. This is why i like this new feature
@@IIARROWS well in fact it can be null. If you mess up and forget to provide the property. That's why I think = default! (except for injected values) or turning off NRT is a bad idea. Just create a constructor for required properties. With named parameters it almost looks like property initialization. That being said the required keyword is better and I will replace my constructors with it.
I really like that they're adding more tools for api/tool code to demand correct usage through compiler errors rather than runtime errors, that's the most powerful thing a compiled language can do to help us
The discussion in the issue is very interesting. Personally I prefer "public string X { get; required init; }".
Likewise, I think this would add huge amounts of clarity to code.
Attribute constructors means something like [Required(ErorrMessage="Error")] as an example
Oh I see! Thanks
Yes. I was thinking the same.
I thought the same.
I wonder if this can be made to eliminate the boilerplate around defining and assigning dependencies in dependency injection
Maybe this? public required IFoo Foo { init; }
This is great in theory, but only for simple constructors. Any time you have to initialize a collection property with an empty List, you’ll be right back to doing it the old way.
You can just initialize the property with an empty list. No need to do that in a ctor.
I just hope this works well with JSON serialization. That requires a parameterless constructor for deserialization anyways most of the time, so the required keyboard spares me a lot of checking code. I appreciate it immensely. And I also also highly appreciate the work you're doing with Videos and courses.
Constructors also work though. Been using records with json serialization which are very concise for this.
Any updates on this? I remember using deserialization skipped a lot of the initialization rules we had in the past, such as defaulting a property to an empty collection, both in the constructor or as a default property assignment. C# basically just created an object from what it was given and ran nothing else, so it always made sense for us to just have a validation service that would run. Or in this case, "correct" the data. Treating it like a DTO and then mapping to a full fledged object probably would have been the better choice, but live and learn when maintaining feature parity across multiple code bases simultaneously lol.
I'll be using it for sure. I was actually waiting for such a feature.
This helps patch the huge hole created with non-nullable types on properties. Now you won't be able to forget to initialize those important properties. Constructors were sometimes an option but often felt too clunky to use. I'm so glad this feature is finally coming to c#.
what if i need to run a class method to initialize a property? i would normally run it in the constructor and assign its return value to the property but like this, without a constructor, i'd have to delegate that to an external method in order to call it during initialization. maybe this will come in handy for a few scenario but constructors will still be needed for complex inits
I felt it when you showed the constructor where each line had a value to pass in required fields. I’ve been in that scenario far too many times. I was also in a bit of a pickle because the settings for our quality gate, SonarCloud, restricted the number or arguments for methods including constructors. So in the end I ended up resorting to “smuggling” arguments in a class solely built for passing all the arguments I needed. I do like the idea of transforming object initializers into de facto customizable constructors with the ability to declare required properties. I’ve been out of the loop for a while due to health issues so I’ve been enjoying catching up watching Nick. Thanks Nick!
That would be WONDERFUL!! I'll use it a lot... well it depends on what exactly mean "required" for a string.
I’m curious to see if classes with the [RequiredMember] attribute will impact Activator.CreateInstance()… mainly from the perspective of a library/framework maintainer…
I haven't read through the proposal or related media, but based on what I saw here it looks like it's something that only happens at compile time for statically known things, which Activator and co. already don't care about. I imagine this changes nothing since the default constructor should still exist, but I can see a world where they throw an exception I guess.
Dude gets people hyped for a c# release like none other
Oooo this is nice, I can stop using named parameters to essentially get the nice explicitness of initiaze lists with required variables
Really glad to see this finally making it into the language, I've wanted this feature for a long time.
Seems almost like a constructor with braces instead of parentheses. Defining by marking the properties themselves as required is nicer than defining the same concept in a constructor. But it is basically the same thing.
My only issue is if some property is partially required. For example if another property is set like if MiddleName is set then FirstName is required. This should probably be solved by an abstract factory but constructors would also be a solution aka having Person(string first) { } Person(string first, string middle) { } Person(string first, string middle, string last) { }. However it would be good to put required on the first name.
I have expected for this for long time.
I got tired of using ctor just to enforce required members initialization.
I Think I would use that a lot!
This looks very nice, but i have a big problem with this feature. You cannot do any validation based on the member. A sample would be: You have the properties Start and End and want to validate that Start is smaller than end. How can you handle it with this feature? Constructor is called before any value is set and if you do the logic in the properties the order matters.
PS: Sorry for my bad english
You can add it in the setter which is really where it should be. Ctor only ensures the creation but not any subsequent value setting
I love it. I have hated constructors for dto unless you go the full record route. And doing nullable makes it more difficult because you have to assign fake values everywhere. Now you can just require and not deal with string.empty everywhere.
Thank you as always
that feature comes from dart, dart is the language of flutter, in dart you may declare a variable as required on the constructor then you must provide a initial value or the compiler throw a error
With the 'required' keyword on the horizon, it feels like C# is finally turning up the volume on its safety feature. Forget constructors, it's all about concise and clean code now. It's like spring cleaning, but for our codebase!
I kind of take the opposite view: Where initializers exist, they're evidence of a deficiency in the provided constructor(s) on the class. If you have to assign 10 properties to the object to initialize it correctly, the problem isn't that you have a really big constructor; it's that you have a God Object that needs massive amounts of initialization to work correctly.
Great video as always! I'm wondering if DI containers will support the required keyword. As far as I know, all of them rely on constructors for automatically determining which dependencies should be injected.
I don't think they will because I don't think it will solve the same problem. The main reason why required makes sense for POCOs (mostly) is that you actually initialize them yourself. For classes with injected dependencies, you never initialize them explicitly (except for unit testing when you pass the mocks)
lets wait 5 more versions of c# to have *inject* keyword 😀
It will be one of the best features, especially with the recent null state analysis.
"= null!" no more
Nick - thank you for such a well explained video on the upcoming feature.
Hey Nick, I would love to see an ASP Net Core class that ignores MVC and focuses purely on the API side using best practices such as mediator and any other libraries you reccomend. If one already exists usisng C# 10 it would be great to hear your reccomendation. All of the tutorials I find focus on MVC and not the API / server side of things. This is interesting for me as I mostly use Blazor WASM as a front end and having a rock solid server side deployment would help make my application enterprise ready.
I saw that feature on dart and I’m glad it is coming to C# as well, great video, btw
Yeah init was not enough. I was thinking about this yesterday and this video shows up. Kudos
I wonder how it will work in Entity Framework. How EF will bypass such feature.
That's a nice feature. The more boilerplate unnecessary code they can remove, the better c#/.Net coding experience gets.
I'd love to get rid of constructors just for dependency injection as well. Just add a "injected" keyword instead
How would you mock it? If you set it using object initialization it uses that, otherwise it injects? That'd be cool
What is the difference between the init in the property and only a get? In both cases i can only set the Property in the constructor.
So this should remove the dreaded " = null!;" after all my properties?
Yeap!
Genuinely asking here; in what scenario do you need to do = null! after your properties? It sounds like a huge red flag to me.
@@petrusion2827 It's when you know for absolute certain that a property isn't nullable (using NRTs) but you need to suppress the nullability warnings of C#.It's usually when a field is init only but you don't want to make a constructor to suppress it. It's pretty standard and even Microsoft code uses it, even though I think they do "= default!" not "null!"
@@nickchapsas I'm having some trouble wrapping my head around this. Without the required keyword, aren't you risking that the caller won't initialize the property, making it null?
@@petrusion2827 There is a slight risk. In my case those properties are DTOs only used to receive json api requests, and we already have validations that return 4xx responses if thoses properties are not populated.
Hi Nick. I just found your channel a couple days ago and I'm loving it! Keep up the good work!
Are you able to "initialize" the required FullName with null or string.Empty?
I'm likely to stick with constructors. It is rare to have more than a few parameters, and it is the perfect place to verify values.
I would argue it is a bad place to verify the values actually. Should it really be the responsibility of the class itself to know what values are valid? For all the types of models? Both API contracts, Domain object and database DTOs? I'd rather have a centralised piece of code that validates instead of spreading my validation integrity which can lead to problems.
@@nickchapsas Well, taking something from DDD, you can use a Value Object for FullName and I'd say it's totally its responsibility to check valid values for its invariants like don't accept empty strings or null as internal values. Then the Person class should just validate against null FullName values, otherwise, I'd say you're having a kind of anemic domain model.
If you combine it with the field keyword (please tell me it will be in C# 11), you could do your checks in the setter before assigning the value in the backing field.
@@nickchapsas Yes - it is the class's responsibility to verify it's own data integrity. Who else knows better? Granted, a class might consult global and/or injected values to decide what values are valid, but that logic is the responsibility of the class. The old-fashioned term for this is "encapsulation".
I am indeed old-fashioned - I started learning C# in 2002, and was a C++ & Turbo Pascal programmer since 1988. So I humbly admit I may just be howling at the moon of modernity.
@@Krimog Yes, field will be included.
I like this, I always preferred to use constructor parameters but this approach makes it even better
This is awesome for writing API code and models and now would make the intent much better at compile time!
What a about validation practices during object initialization? Should it go on setter then, isntead for ctor?
One my next new favorite C# features !!
This is great and I look forward to the required keyword, but at the same time, it shouldn't be required if the language was properly designed because we already have nullable and non-nullable data types, so it should already know that the property is required if it is not nullable, but I guess this is because of backwards compatibility.
Thank you! I would definitely use this. I have needed it for at long time. Also, if you need a xaml control that needed some startup properties, you can't use a constructor for that. As far as I know, there is not "logic" way of making it obvious for the user of your control, which fields are neccessary and which are not. I hope they will make this work with the xaml compiler, so it gets angry if the required fields are not set inside the control element, or at least an option to make it so.
I really liked this feature, but I'm still think how it's gonna be for dependency injection via constructor ? It's gonna stay the same?
I like your videos.
And I like that you use allman braces. They're nicely readable for people with bad eyesight like me.
Hrm. I guess that's good if you don't do any validation of constructor params. What about initializing the instance with a string.Empty or " " (Whitespace) for FullName property? Can we do validation and throw InvalidArgumentException with required/init?
The benefit of having constructors is it makes your classes neater IMO. The logic for setting a properties of a class should be within the class itself otherwise you end up having instanciations of your object all over the project. It also makes it easier to read what's implementing that object when using the "2 references" (visual studio enterprise)
The required keyword on it's own is not meant to replace any meaningful "logic" that would usually be found in a constructor. Instead it is replacing the unnecessary legwork of having to create huge unwieldy constructors which do nothing but take a bunch of mandatory parameters and assign them to properties/fields.
If you want to implement custom logic during initialization you can still use constructors as before for those properties/fields that need it and use the required keyword for all other mandatory ones. Same as you would use auto properties to simplify get/set access to a single line and only implement custom get/set logic as needed.
Also another neat C#11 feature which Nick has not mentioned goes very well with this:
You get field access in auto properties: Each accessor in an auto property will be able to implement themselves and can *refer* *to* *the* *automatically* *allocated* *backing* *field* with the fittingly named keyword *"field".* Example:
public required string FirstName { get; init => field = value.Trim() }
OFF TOPIC Question > What extension, besides Sonarlint, is good for Visual Studio, in order to check Debt Metrics, Code Complexity, etc.? Something like Stepsize Debt Metrics for VS Code...
One of my main problems with records is actually that they don't have the pretty class init syntax. I think It is way more readable than using constructor when initting records (even though you can use named parameters). Very excited for this feature to land!
It's more verbose, but you can declare records and just not provide the parameter list. You'd be writing the same { get; init; } properties manually instead, but you get the initializer syntax back. For more complicated records this is what I currently do because the benefit of compiler generated Equals/HashCode is sometimes worth it, just missing the required marker still : (
Even though this wouldn’t be used for DI, it still gave me a feeling that DI could be trimmed down substantially with a similar approach. We’re almost always doing the same boilerplating in DI (except for e.g. the Options pattern), so reducing it all down to the field with a keyword such as ”inject” or something would make the code a lot more beautiful and completely remove the need for constructors in most cases!
Almost all DI already have this autowire properties functionality. But ctors are better. From point of view autofac is number one especially with optional injections, factory injections etc
@@ztBlackGad True but I don't want to use properties for DI. Just feels wrong to me. Private readonly variables only...
@@briankarcher8338 then how to mock dependencies? :)
@@ztBlackGad Constructor. These variables should be kept encapsulated.
@@ztBlackGad Mind you, I wouldn't mind some sort of attribute or something to mark a private field as an injected field as mentioned by others in the comments. DI can get really heavy on the constructor - too much boilerplate that is unnecessary and not that hard to fix if Microsoft/3rd parties wanted to fix it at the compiler/library level.
Sounds interesting, but we can't say that we won't need constructors. What if I want to encapsulate properties or class members? If I do with this approach, class inner fields must be an ''public', which brakes an Encapsulation approach, because members are visible outside of class. So, in my opinion right place to use it is DTO classes where we need to be initialized their members when we're creating its object. Thanks ;)
Is this feature compatible with the ASP NET Core dependency injector in the sense that we would no longer need to initialize the dependency fields/properties inside the service class constructor, or am I getting it wrong?
This isn't really applicable to DI because with DI you never had to manually provide those values in the ctor. It's done automatically by the IoC container.
@@nickchapsas Well I guess it makes sense, but I really hoped that the new feature could reduce some of the boilerplate code related to the DI sad 😞
Cool, something that I could never do before is now actually possible :). I wrote my own DI Container long time ago that uses MEF-like attributes and field-injection and I got massive problems with nullable-reference types. BTW, I love attributes because they tell me exactly how a class plays a role in the infrastructure in comparison to other DI DI containers where I have no clue whether the class should be manually instantiated or retrieved from DI container, I imidiatelly see what dependencies a class has, I don't need to use constructor and extra code to set the fields, and I don't need to register each class. For instance:
[Export]
public class C
{
[Import]
private D dependency;
}
I got warnings that property is not nullable but is also not initialized directly in code. I don't want it to be nullable because it is not optional and DI container will throw an error while bootstrapping the application if dependency is missing. Using "required" keyword could solve this big problem.
[Export]
public class C
{
[Import]
private required D dependency { get; init; }
}
I would have to use private properties instead, but it's fine and not much more code to write. But I need to experiment with the feature if it would actually work.
Excellent video! At time mark 5:00, what are you using to draw on your screen so quickly?
Can you use the required keyword without the init attribute? As in you have to provide when creating the object, but you can change it later?
Very nice feature, thanks!
Love this feature, can't wait to use it
Does that mean that safe generic object creation will be possible, i.e. the following will be possible and compiler enforced if IFoo has required property Bar?
public TFoo CreateFoo()
where TFoo : new(), IFoo
=> new TFoo { Bar = "Baz" };
Well, with constructor you can do this: new(arg1: value1, arg2: value2, ...); you can omit the name, you can still have argument names; others have raised interesting questions, for example how does this work with reflection. To me, using an explicit constructor would be better, also esthetically it would be practically the same as new Class { args = blah }; we'll see i guess.
You can't always do so. For example in Expression trees (Linq to Sql for example, used in EF queries) this is prohibited.
true but it's also quite a special context anyway
Could someone tell if it works with Dependency Injection Registration?
Convenient feature. if you have a ctor with 10 parameters maybe you could use a builder though
Builders are hard when you need to do programmatic stuff with that type, for example writing a serializer. I like it being an option but not the only way unless there is a very specific reason, for example guided initialization
Not gonna lie, this seems really strange to me, I would question why do this when records were just created which still forces that limiting by constructor approch. I'd rather have seen a 'auto generate constructor' rather than having required property construction. Seems like a split path just to try and please everyone.
Hello what do you use to be able to use annotation in your screen ?
So... What if the constructor contains some precalculation logic? For example, do we want to evaluate a regular expression pattern before instantiating a class?
Not a fan of that. If you really care about that, put it in the setter to make sure that every time the value changes the validation is triggered
Nick doesn't need constructors because he's simply so powerful he can instantiate objects by sheer force of will
How would a class like that be handled when it's injected by an dependency injection?
btw, what about overload constructor?
15 seconds into the video and im already sold
Once this was explained, I realized how useful it is. Cool!
I'm looking formward to this, wonder how well it will work with json deserialization.
Great news! That's one of the reasons I was so upset about using nullability features in C#. They forced me to use constructors to init properties. And I don't make use of constructors for most of my programming thigns.
Constructors already allowed for named parameters to be given. As far as I can tell the only change here is now that you can write exactly the same syntax but with curly braces instead of parentheses?
hello Nick awesome content, I just bought your class about testing (used the code and still worked, yaay!), looking forward to watch it, what I would like to see more is some high performance optimizations, usage of spans, seems like C#11 is moving in that direction with utf support and patter matching, do you think Span will be for mainstream use and proliferate thru most modern c# codebases? Can you consider making course going in depth on this topic - performance, memory allocation and usage of span and memory?
There is actually a course about writing performant c# code coming hopefully this year. It’s really something I wanna make more content about
I'm torn on this feature. It's definitely good for readability of the code, especially outside of IDE (Pull Requests/Github etc), where you don't see what each constructor parameter actually is. But for developer experience while writing the code I see issues.
This is nice for a model with 2 properties.
Model with dozen(s) properties will be much harder to use with this feature, simply because devs will now have to discover which properties are required and must be set. Before that'd be solved with constructor that provides structured way of showing which parameters are required and which are optional.
Also I've been switching to using records for any POCO/DTO type classes anyway, and those have the opposite approach with being set via the constructors.
SO I dunno, I feel like this feature is, for now, tact on and sort of starts to interfere with other features they've been introducing. It will also largly depend on good IDE support to help with required property discovery. I'll see how it's handling in "real world" while it's released and what scenarios it becomes better than records, for example. Maybe IOptions, that do not support constructor parameter values injection? Dunno, we'll see.
You can also declare records without constructor, just like normal classes and use object initializer.
This is the comment I was looking for
I think this actually make development more precise.
I wonder how this mixes with serialization.
This works very similar to the new features in PHP 8? Out of interest as a c# noob does c# support named function arguments ? Like in PHP 8 it solves the issue in my opinion of constructors with lots of arguments.
I'd say: really neat for data classes but I wouldn't use this for anything that requires DI.
Say you need to register to an event on your dependency then this would now need to happen in the property setter. And I'd rather have all my initialization logic for a class in one neat place.
Also if you ever needed two of your dependencies for some initialization call you'd suddenly have an invisible required order of how your properties need to be set because otherwise the code breaks. And the bad part about it is of course that that requirement can happen down the line and then your only sensible approach to that would of course be to go back to having a constructor. But at that point that would be a breaking change (granted the Di-container really shouldn't care about that breaking change but all your unit tests will mind very much so it's still quite a hassle)
So tl;dr; will use that for POCOs but not for anything with logic.
My only question is if this will work with dependency injection
Is this [RequiredMemberAttribute] stays after lowering and can be inspected by reflection?
I haven't tried it but I am pretty positive that it can yeah
@@nickchapsas Then this feature looks very useful, I can combine it for compile time validation and later reflection based validation of busines logic entities after json deserialization.
But how does do Dependency Injection?
This is fantastic. Constructors are such an old legacy way of initializing things and being able to not have to use one is amazing 🤩
This great especially when doing refactoring. However multiple overloads was used to have some different options and flow, but given from the example using model I can see many reasons why.
Does it handle Guards, even if the string is required you could put it as an empty string right? Else I'm still stuck with constructors or static factories for my domain objects.
I'd rather have guards in setters than the Ctor. What if a property is mutable?
How would this help in constructor dependency injection?
It wouldn't but it's not for that usecase. In DI it's not a problem because you don't manually use the constructor, it is done for you by the ioc container
Hi Nick, thank you for your videos. Why do u always use num 69 as an example number? Is that mystery num for ya? ;)
Well presented Νίκο! Thanks for the content!
While I like the idea of the feature, it takes away the ability to explicitly know how to create a class without dealing with errors. Having the values in the constructor at least tells you right away what is required to make the class. This feature you won't know, until you see errors.
So it just needs IDE support for suggestions, not a big deal to implement.
I'm sure they'll have that as well; however, how does that help when looking at documentation of a library? Now you not only have to look at constructors but the properties as well just to figure out how to instantiate it. I just fail to see how this speeds up development.
Reminds me how in records you don't see the argument names like in a property initializer
Agree, and what about polymorpishm, multiple constructors with different required parameters. This is ugly way. I can not imagine big app written with this way. Huh
@@jakubhantak1960 actually having multiple constructors that initialize different sets of properties is a code smell and this pretty much eliminates that code smell, so it's a win.
I’m a bit confused. I don’t have that much experience with .NET and c# but how is this different from adding required data annotation, isn’t that the same or is that just for validation?
This is OK for POCO classes, but what if I don't want string property to have empty string, or I need to perform some specific domain validation. So in the end ctors or static factory methods are still way to go.
Nick: Why I won't need constructors anymore
System.Text.Json: Hello
This functionality was really lacking before, but the option when the initialized object has fields in the constructor and required fields does not look very good 😅
I would love to have this. I only wish I could dind a migration path from Framework, which doesn’t and won’t support modern C#. This is mainly a question of updating UI from WPF.
This seems like a lowering change, which means it's supported in .Net Framework. Most language changes are supported on Framework.
I only know of two things that aren't (I'm sure there are others): Default Interface Implementations, and the `with` keyword for structs. Every other thing I've tried (up to and including C# 10) works on .Net Framework 4.8
So much syntax sugar were added lately that I'm sure C# 69 would be the sweetest thing ever.
True!
Same thing with Python
Great video! Thanks for the content!
An old school approach to eliminating noisy constructors has been passing in a single class to the constructor that contained all the initial property values. I do like learning new ways to accomplish a problem. Where I work I am forced to work in .net 2.0 for the systems I work on.
Having a constructor with a long list of inputs is a design smell anyway, so it's probably better that data is being passed around in smaller classes anyway
I dunno, it just looks sugar to me... What was the problem with (overloading) constructors, again?
Hmm, I don't know... at the end of the day you gotta write this down anyway AND you have extra keyword to learn. But I guess nothing beats adding the 'nullable' feature: you code it like a pointer but it has a fragment of the functionality.
This works with the nullable feature. In fact it is what makes it actually work instead of having to fake suppress warning withs "= default!" and "= null!"
But nick why we can not assign value after initialization
You can... when you mark the property 'set'. Then you are allowed to set/change it whenever.
But lets not forget that this is kind of the whole point of the 'init' keyword in the property.
By marking it as such you essentially say the only time you can set it is when you create an instance and never after.
the 'set' can, depending on your class/code of course, be a real nightmare as 'set' implies that the value could all of a sudden change during the lifetime of the instance. You have to add boiler plate code like checks etc.
So in order to make sure people can only set a value during instantiation AND are forced to do so... is what the 'required' keyword here does.
I imagine that the check is on the codeDom side or at least at compile time
What happends if you instanciate a person at runtime like this :
var person = (Person)typeof(Person).GetConstructor(new Type[] { }).Invoke(new object[] { });