Why I won’t need constructors anymore in C# 11

  Рет қаралды 134,874

Nick Chapsas

Nick Chapsas

Жыл бұрын

Check out my new "Integration testing in ASP .NET Core" course and use code INTESTING1 for 20% off (first 300): dometrain.com/course/from-zer...
Become a Patreon and get source code access: / nickchapsas
Hello everybody I'm Nick and in this video I will introduce you to the brand new "required" keyword that is being added in C# 11. It is a great language feature that solves one of my biggest problems with object initialization, and it eliminated the need for constructors for that usecase.
Link to the required keyword feature issue: github.com/dotnet/csharplang/...
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasGitHub
Follow me on Twitter: bit.ly/ChapsasTwitter
Connect on LinkedIn: bit.ly/ChapsasLinkedIn
Keep coding merch: keepcoding.shop
#csharp #dotnet

Пікірлер: 404
@nickchapsas
@nickchapsas Жыл бұрын
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
@tisurmaster
@tisurmaster Жыл бұрын
would you be able to use it to write api's? API should be simple.
@DavidBondOnline
@DavidBondOnline Жыл бұрын
This is great news! Will it play nicely with deserialization, I wonder?
@RasmusSchultz
@RasmusSchultz Жыл бұрын
YES! FINALLY! 😄 No more boilerplate constructors duplicating every name and type of every property. Sheesh! We needed this 😅
@RasmusSchultz
@RasmusSchultz Жыл бұрын
@@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.
@user-zz6fk8bc8u
@user-zz6fk8bc8u Жыл бұрын
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.
@antonmartyniuk
@antonmartyniuk Жыл бұрын
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
@Dhaiky
@Dhaiky Жыл бұрын
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
@DanteDeRuwe
@DanteDeRuwe Жыл бұрын
Was going to comment something very similar. Very nice that it's finally coming!
@BadgersEscape
@BadgersEscape Жыл бұрын
"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.)
@qcqe
@qcqe Жыл бұрын
@@BadgersEscape I do that, makes my code look very enterprise/shitty
@travisabrahamson8864
@travisabrahamson8864 Жыл бұрын
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.
@nickchapsas
@nickchapsas Жыл бұрын
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
@georget10i
@georget10i Жыл бұрын
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?
@TheRuko15
@TheRuko15 Жыл бұрын
Hi Nick. I just found your channel a couple days ago and I'm loving it! Keep up the good work!
@mikemcaulay9507
@mikemcaulay9507 Жыл бұрын
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!
@JonathanLindeque
@JonathanLindeque Жыл бұрын
Nick - thank you for such a well explained video on the upcoming feature.
@user-dc9zo7ek5j
@user-dc9zo7ek5j Жыл бұрын
Note that properties are not the same as constructors, and the compiled code is much bigger, and thus inefficient compared to the constructors, because each property is set externally outside the class. Funny enough, we even bloat out the source code with by using Property = value and setting each property on a new line and such. I think records is one of the features that really helped with making classes short and clean. Plus, when implementing a new feature you can add a parameter to your constructor, or another parameter to the record, and you can safely go through all the places where the class has been instantiated. With properties it's a little harder, since you can't really see where it has been created. We really don't need any more ways to create a class neither instantiate the properties, seriously, we could write a top 10 ways to create an object in c#.
@cn-ml
@cn-ml Жыл бұрын
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.
@nickchapsas
@nickchapsas Жыл бұрын
You can finally say goodbye to those "= default!" calls. it also makes working with deserializer code so much easier
@cn-ml
@cn-ml Жыл бұрын
@@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
@cyril113
@cyril113 Жыл бұрын
@@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.
@EtienneFortin
@EtienneFortin Жыл бұрын
I'll be using it for sure. I was actually waiting for such a feature.
@andrewrichesson8627
@andrewrichesson8627 Жыл бұрын
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#.
@octe-es
@octe-es Жыл бұрын
I saw that feature on dart and I’m glad it is coming to C# as well, great video, btw
@meirkr
@meirkr Жыл бұрын
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!
@nanvlad
@nanvlad Жыл бұрын
Attribute constructors means something like [Required(ErorrMessage="Error")] as an example
@nickchapsas
@nickchapsas Жыл бұрын
Oh I see! Thanks
@pqsk
@pqsk Жыл бұрын
Yes. I was thinking the same.
@deltaphilip8611
@deltaphilip8611 Жыл бұрын
I thought the same.
@T___Brown
@T___Brown Жыл бұрын
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
@soucianceeqdamrashti8175
@soucianceeqdamrashti8175 Жыл бұрын
This is awesome for writing API code and models and now would make the intent much better at compile time!
@pavfrang
@pavfrang Жыл бұрын
Well presented Νίκο! Thanks for the content!
@damaomiX
@damaomiX Жыл бұрын
The discussion in the issue is very interesting. Personally I prefer "public string X { get; required init; }".
@vidennn
@vidennn Жыл бұрын
Likewise, I think this would add huge amounts of clarity to code.
@IRofledTheL0L
@IRofledTheL0L Жыл бұрын
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.
@Rick104547
@Rick104547 Жыл бұрын
Constructors also work though. Been using records with json serialization which are very concise for this.
@ps2goat
@ps2goat 8 ай бұрын
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.
@Hantick
@Hantick Жыл бұрын
I like this, I always preferred to use constructor parameters but this approach makes it even better
@figloalds
@figloalds Жыл бұрын
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
@Flem100DK
@Flem100DK Жыл бұрын
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.
@ShawnShaddock
@ShawnShaddock Жыл бұрын
Really glad to see this finally making it into the language, I've wanted this feature for a long time.
@russellhorwood798
@russellhorwood798 Жыл бұрын
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.
@TomBauto
@TomBauto Жыл бұрын
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.
@FabioMaulo
@FabioMaulo Жыл бұрын
That would be WONDERFUL!! I'll use it a lot... well it depends on what exactly mean "required" for a string.
@swedishprogrammer
@swedishprogrammer Жыл бұрын
Great video! Thanks for the content!
@enricolus521
@enricolus521 Жыл бұрын
Love this feature, can't wait to use it
@Manlyman789
@Manlyman789 Жыл бұрын
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.
@maurosampietro9900
@maurosampietro9900 Жыл бұрын
Yeah init was not enough. I was thinking about this yesterday and this video shows up. Kudos
@IAmFeO2x
@IAmFeO2x Жыл бұрын
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.
@nickchapsas
@nickchapsas Жыл бұрын
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)
@krzysztofklein3057
@krzysztofklein3057 Жыл бұрын
lets wait 5 more versions of c# to have *inject* keyword 😀
@hamedsalameh8155
@hamedsalameh8155 Жыл бұрын
One my next new favorite C# features !!
@tomazkoritnik4072
@tomazkoritnik4072 Жыл бұрын
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.
@erril8285
@erril8285 Жыл бұрын
Very nice feature, thanks!
@chefbennyj
@chefbennyj Жыл бұрын
Once this was explained, I realized how useful it is. Cool!
@Bliss467
@Bliss467 Жыл бұрын
I wonder if this can be made to eliminate the boilerplate around defining and assigning dependencies in dependency injection
@leejasongrissom
@leejasongrissom Жыл бұрын
Maybe this? public required IFoo Foo { init; }
@ChrisPepper1989
@ChrisPepper1989 Жыл бұрын
Oooo this is nice, I can stop using named parameters to essentially get the nice explicitness of initiaze lists with required variables
@neilsg2001
@neilsg2001 8 ай бұрын
Thank you 👍🏻👍🏻
@jamesmussett
@jamesmussett Жыл бұрын
I’m curious to see if classes with the [RequiredMember] attribute will impact Activator.CreateInstance()… mainly from the perspective of a library/framework maintainer…
@localatticus4748
@localatticus4748 Жыл бұрын
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.
@TheRedBaron619
@TheRedBaron619 Жыл бұрын
Excellent video! At time mark 5:00, what are you using to draw on your screen so quickly?
@vmachacek
@vmachacek Жыл бұрын
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?
@nickchapsas
@nickchapsas Жыл бұрын
There is actually a course about writing performant c# code coming hopefully this year. It’s really something I wanna make more content about
@vukkulvar9769
@vukkulvar9769 Жыл бұрын
I like your videos. And I like that you use allman braces. They're nicely readable for people with bad eyesight like me.
@RobertMcLaws
@RobertMcLaws Жыл бұрын
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.
@EspenSkaufel
@EspenSkaufel Жыл бұрын
You can just initialize the property with an empty list. No need to do that in a ctor.
@alfonsosuarez9317
@alfonsosuarez9317 Жыл бұрын
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.
@ryanjeffares8238
@ryanjeffares8238 Жыл бұрын
This is cool, Dart has a similar feature and I always thought that language had really nice semantics around initialisation/constructors. Slightly unrelated question about lowering in C# - do you know if the lowering process takes place in a more abstract way in the AST the compiler generates, or is it actually stored as text in memory by the compiler before parsing?
@nickchapsas
@nickchapsas Жыл бұрын
It's its own step under the LocalRewriter folder in Roslyn: github.com/dotnet/roslyn/tree/main/src/Compilers/CSharp/Portable/Lowering/LocalRewriter
@ryanjeffares8238
@ryanjeffares8238 Жыл бұрын
@@nickchapsas Cool, at a glance it looks like it takes place in the AST nodes. Thanks for the link and all the content!
@ukapas
@ukapas Жыл бұрын
This one seems really handy!
@MRApht
@MRApht Жыл бұрын
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!
@localatticus4748
@localatticus4748 Жыл бұрын
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 : (
@TheUruz
@TheUruz Жыл бұрын
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
@freshouttathebag7725
@freshouttathebag7725 Жыл бұрын
Dude gets people hyped for a c# release like none other
@amrosamy8232
@amrosamy8232 Жыл бұрын
Amazing 👏 I wonder if it works while calling a method with input class that has required properties This may improve the method input limitations
@raphaelmt1706
@raphaelmt1706 Жыл бұрын
I'm looking formward to this, wonder how well it will work with json deserialization.
@JensDll
@JensDll Жыл бұрын
It will be one of the best features, especially with the recent null state analysis.
@JensDll
@JensDll Жыл бұрын
"= null!" no more
@haroldpepete
@haroldpepete Жыл бұрын
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
@masonwheeler6536
@masonwheeler6536 Жыл бұрын
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.
@efdrgn
@efdrgn Жыл бұрын
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)
@fabiant.2485
@fabiant.2485 Жыл бұрын
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() }
@granmasterlincoln
@granmasterlincoln Жыл бұрын
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?
@twiksify
@twiksify Жыл бұрын
This would make DI so much neater, looking forward to it. Will the compiled code keep the constraint such that this will work even if the class is used from a dll?
@stindare2230
@stindare2230 Жыл бұрын
Why would it make DI neater? Most of what I've seen that's dependency injected gets assigned to private fields, not properties.
@tomaszzielinski1704
@tomaszzielinski1704 Жыл бұрын
What if you call code compiled with this feature from code without this feature available. Will the compiler show error for unknown annotation or silently initialize required value to null?
@nitsud001
@nitsud001 Жыл бұрын
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?
@crazyfox55
@crazyfox55 Жыл бұрын
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.
@Vinoyl
@Vinoyl Жыл бұрын
15 seconds into the video and im already sold
@fred.flintstone4099
@fred.flintstone4099 Жыл бұрын
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.
@codingpeanuts
@codingpeanuts 11 ай бұрын
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!
@dgschrei
@dgschrei Жыл бұрын
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.
@woistdasniveau8290
@woistdasniveau8290 Жыл бұрын
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.
@sofienielsen4608
@sofienielsen4608 Жыл бұрын
Would be nice as to avoid long constructors when having to make a UML, Though for that to work UML would have to have a way of indicating required variables, and i dont think that is a thing, correct me if I'm wrong.
@CodeThatVoid
@CodeThatVoid Жыл бұрын
What a about validation practices during object initialization? Should it go on setter then, isntead for ctor?
@modernkennnern
@modernkennnern Жыл бұрын
This is fantastic. Constructors are such an old legacy way of initializing things and being able to not have to use one is amazing 🤩
@justwatching6118
@justwatching6118 Жыл бұрын
This is AWESOME! ... ❤❤❤❤❤
@roman.sattler
@roman.sattler Жыл бұрын
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" };
@B08AH
@B08AH 8 ай бұрын
Nice feature
@andreikhotko5206
@andreikhotko5206 Жыл бұрын
Could someone tell if it works with Dependency Injection Registration?
@YB-me3pq
@YB-me3pq Жыл бұрын
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?
@responsibleparty
@responsibleparty Жыл бұрын
Where this could be interesting is with places like Entity classes and maybe Razor Pages code files. I often end up disabling nullable reference types in these files because adding massive constructors or having to check for null every time I use a property is not practical. So I'm assuming this was in response to nullable reference types and initially it didn't sound like something I needed but now I'm thinking maybe I do.
@user-ns9kt5zm8v
@user-ns9kt5zm8v Жыл бұрын
I wonder how it will work in Entity Framework. How EF will bypass such feature.
@BigKevSexyMan
@BigKevSexyMan Жыл бұрын
I'd use this all the time, but I am curious how intellisense and the IDE work with it. Currently for constructors you just type your parameters in order and the intellisense gives you whatever comments are tied to those parameters so you can be informed about what you are putting in. I imagine the intellisense would work similarly for each required variable, but it would be even nicer if you could press a keyboard shortcut and have the IDE type out all the required and optional variables you can set as well as include the comments describing those. It could make using an object much easier to read and understand for someone looking over code or who is new to the object library being used.
@metlic5209
@metlic5209 Жыл бұрын
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.
@vorontsovru270895
@vorontsovru270895 Жыл бұрын
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 😅
@TheAaandyyy
@TheAaandyyy Жыл бұрын
At the end of the video you said that there will be a link in the description, but I cannot find it. Could you maybe link it? I wonder how this feature behaves with Activator.CreateInstance() method.
@nickchapsas
@nickchapsas Жыл бұрын
Good question. I just tested it and it could initialize the class without and error. The field was null
@serb1146
@serb1146 Жыл бұрын
Hi Nick, thank you for your videos. Why do u always use num 69 as an example number? Is that mystery num for ya? ;)
@Ishai1
@Ishai1 Жыл бұрын
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
@modernkennnern
@modernkennnern Жыл бұрын
How would you mock it? If you set it using object initialization it uses that, otherwise it injects? That'd be cool
@christianmilson3720
@christianmilson3720 Жыл бұрын
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.
@Shocker65656
@Shocker65656 Жыл бұрын
I wonder how this required keyword interacts with the Action delegates you covered in your previous video
@aforslow
@aforslow Жыл бұрын
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!
@ztBlackGad
@ztBlackGad Жыл бұрын
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
@briankarcher8338
@briankarcher8338 Жыл бұрын
@@ztBlackGad True but I don't want to use properties for DI. Just feels wrong to me. Private readonly variables only...
@ztBlackGad
@ztBlackGad Жыл бұрын
@@briankarcher8338 then how to mock dependencies? :)
@briankarcher8338
@briankarcher8338 Жыл бұрын
@@ztBlackGad Constructor. These variables should be kept encapsulated.
@briankarcher8338
@briankarcher8338 Жыл бұрын
@@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.
@supercoolninja
@supercoolninja Жыл бұрын
Hello what do you use to be able to use annotation in your screen ?
@ME-dg5np
@ME-dg5np Жыл бұрын
Very useful ! 🕺👍
@kenbrady119
@kenbrady119 Жыл бұрын
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.
@nickchapsas
@nickchapsas Жыл бұрын
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.
@ruekkart
@ruekkart Жыл бұрын
@@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.
@Krimog
@Krimog Жыл бұрын
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.
@kenbrady119
@kenbrady119 Жыл бұрын
@@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.
@obinnaokafor6252
@obinnaokafor6252 Жыл бұрын
@@Krimog Yes, field will be included.
@akosifrylle
@akosifrylle Жыл бұрын
Interesting choice of arbitrary number Nick
@MessageKyle
@MessageKyle Жыл бұрын
I've always just used the [Required] class annotation for my models
@PippiTheLongSock
@PippiTheLongSock Жыл бұрын
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?
@nickchapsas
@nickchapsas Жыл бұрын
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.
@PippiTheLongSock
@PippiTheLongSock Жыл бұрын
@@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 😞
@abj136
@abj136 Жыл бұрын
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.
@modernkennnern
@modernkennnern Жыл бұрын
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
@ivanstoyanov3250
@ivanstoyanov3250 Жыл бұрын
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?
@fullmoonyeah1180
@fullmoonyeah1180 Жыл бұрын
btw, what about overload constructor?
@corsaro0071
@corsaro0071 Жыл бұрын
Convenient feature. if you have a ctor with 10 parameters maybe you could use a builder though
@nickchapsas
@nickchapsas Жыл бұрын
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
@belgarathlesorcier8385
@belgarathlesorcier8385 Жыл бұрын
Neat feature
@elixss304
@elixss304 Жыл бұрын
very nice feature.
@dadwillfixit
@dadwillfixit Жыл бұрын
I wonder how this mixes with serialization.
@RoaringOrange
@RoaringOrange Жыл бұрын
Would be fantastic to have some kind of constructor or initializer method on a class or struct that runs AFTER all property initializers. So we can add logic with all the parameters already in place passed via init properties. This could be achieved by adding [init] attribute to the parameterless private constructor. Or add "init" keyword in front of it. Also, this method can be invoked by deserializers. Just a thought.
@PeriMCS
@PeriMCS Жыл бұрын
@@Eirenarch my thoughts exactly
@user-dc9zo7ek5j
@user-dc9zo7ek5j Жыл бұрын
Could you give me an example of the use case, im curious.
@stanislavsh6582
@stanislavsh6582 Жыл бұрын
So... What if the constructor contains some precalculation logic? For example, do we want to evaluate a regular expression pattern before instantiating a class?
@nickchapsas
@nickchapsas Жыл бұрын
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
@Tsunami14
@Tsunami14 Жыл бұрын
For classes with these required properties, would this no longer satisfy the new() constraint for generics?
@nickchapsas
@nickchapsas Жыл бұрын
new() just specifies that the class needs to have a public parameterless ctor. If you have init only required properties without default values then I assume that your code won't compile
@jerkerolofsson448
@jerkerolofsson448 Жыл бұрын
@@nickchapsas I assume that as the check is only compile-time, creating objects through reflection will still work as well. I was thinking how this will work with for example JSON deserialization.
@soulemful
@soulemful Жыл бұрын
this is pretty sweet.
@mickaelmaroqui
@mickaelmaroqui Жыл бұрын
This looks great, I've been working with init only properties and constructors but it is a pain when it gets bigger. Does the required keywork suppress compiler warnings ? Because I have a lot of those when I don't want a constructor and don't want nullable properties (typically db entity classes)
@nickchapsas
@nickchapsas Жыл бұрын
It does
Properties were getting even cleaner in C# 11
8:12
Nick Chapsas
Рет қаралды 57 М.
Every single feature added in C# 11
27:07
Nick Chapsas
Рет қаралды 109 М.
Follow @karina-kola please 🙏🥺
00:21
Andrey Grechka
Рет қаралды 11 МЛН
Don’t take steroids ! 🙏🙏
00:16
Tibo InShape
Рет қаралды 26 МЛН
The setup "trick" that .NET libraries use and you should too
10:05
Nick Chapsas
Рет қаралды 73 М.
8 await async mistakes that you SHOULD avoid in .NET
21:13
Nick Chapsas
Рет қаралды 306 М.
"Stop Using Async Await in .NET to Save Threads" | Code Cop #018
14:05
Primary Constructors in C# 12 Explained!
9:39
James Montemagno
Рет қаралды 23 М.
Don't Use AutoMapper in C#! Do THIS Instead!
16:17
Codewrinkles
Рет қаралды 64 М.
Adding a BETTER way to loop in C#
9:24
Nick Chapsas
Рет қаралды 77 М.
Don’t Use the Wrong LINQ Methods
12:42
Nick Chapsas
Рет қаралды 45 М.
Why You Might Not Need Interfaces in C# 12
12:43
Nick Chapsas
Рет қаралды 65 М.
Should you stop returning "null"? | Functional C#
11:32
Nick Chapsas
Рет қаралды 104 М.
“Turn All Your Enums Into Bytes Now!” | Code Cop #014
8:43
Nick Chapsas
Рет қаралды 33 М.