Properties were getting even cleaner in C# 11
ฝัง
- เผยแพร่เมื่อ 2 พ.ย. 2024
- Check out my courses: dometrain.com
Become a Patreon and get source code access: / nickchapsas
Hello everybody I'm Nick and in this video I will show you how properties are changing in C# 11 with the introduction of a new feature called Semi-auto properties. This feature will allow you to write less code when dealing with the property's backing field, enabling you to write even more elegant and clean code.
The evolution of properties in C#: • The evolution of Prope...
Semi-auto-properties tracking issue: github.com/dot...
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasG...
Follow me on Twitter: bit.ly/ChapsasT...
Connect on LinkedIn: bit.ly/ChapsasL...
Keep coding merch: keepcoding.shop
#csharp #dotnet
I've been waiting for the "field" feature for so long. I hope it'll finally drop in c# 11 without any issues.
Agreed. Every time I've had to manually create a separate backing field, a part of my soul has died.
IKR, it's mindblowing how such feature is only added now. It already feels like a natural part of the language, and it's not even there yet.
Same here. Don't get why it's not already implemented. It'll kill so many lines of useless code.
Still waiting
Usually I'm against feature bloat, but this feature was well thought out and well designed... It's readable and super useful, I'm all for it.
It’s copied from Kotlin, they didn’t really design much. Still good though
@@orangeguy5374 Yeah it was all ctrl+c ctrl+v, nothing to really think about eh? Such lazy programmers, blergh!
Let's not start about "copying" features from other programming languages - basically *every* programming language in the history of programming languages took inspiration of others and thank god they did, otherwise learning a new language would be a complete nightmare! I'm really sick of an attitude like yours
Absolutely love this feature! I’ve always been annoyed about having to clutter my code with the backing fields.
I like the feature. I don't complain as new keywords and features are added in C#. I like that C# is evolving as a language. And you as a developer choose what language feature you want/need to use and which not. If you don't like new features - it's your right, but one day it may become handy for you. Be pragmatic and not dogmatic
Many different ways to accomplish something scares people off; they mostly want 1 way of doing something "correctly" and not worrying about sifting through 10 different versions of the same code.
I agree to an extent; I just don't think it's reasonable to expect C# devs to keep learning what the language is.
Not evolving leads to stagnation and extinction.
Evolving without the proper footholds can cause weird mutations.
@@computer9764 I think it is very reasonable to expect any human to keep learning.
@@mindstyler Humans should keep learning, but do you really want to learn a different way to do math every time you do it?
@@computer9764 If I could learn a math technique that would require 1 line to calculate something instead of 5 lines, and still be just as easy to understand, then yes.
@@computer9764 if it's better or easier, absolutely
It's the small things that really stack up over time to make working with the language a pleasure to work with. Semi-Auto-Properties will be a nice addition.
Also, I've been watching your videos for some time now and I must say, you provide consistent quality content without a bunch of fluff. Thank you.
I like it. I'm using this functionality with MVVM Community toolkit, and I think it is very nice seeing this as part of the official language specification. Thank you!
MVVM's PropertyChanged-notifications are basically kind of the main-reason to want this feature. Having writing the backing field every time is nothing more than a pain, as it's all just for that notification and nothing more.
How are you doing to use this feature still not released with c# 11 ?
The new way to do lazy inits looks damn clean, I love it!
Very nice! And also the fact that Interfaces got overhault too, (static abstract, operator for something like IIsNumber) it just keeps getting better and better!
Makes resharper and the like
more and more important to discover when to use / apply these new concepts, until they become your second nature.
It was a pleasant surprise to hear your ask a question at the C# 11 talk at NDC CPH, and I instantly recognized your voice! Hope you had a great conference!
This is a feature that is long missed. It was always strange to me that I had "value" without having to declare something like "set(value) { _field = value; }" but had no "field" and thus having to always use an explicit backing field. Now I'm in peace. hahaha
The new features are awesome. I saw Mads what's next in C# 11 video and got excited.
Could you do a video about lock keyword or threads synchronization in general?
What a time to be alive as a C# developer!
This is super cool and will definitely make it's way into my daily to day. I've been wanting these property changes for YEARS. It didn't take much playing around with properties to realize their shortcomings and come up with a laundry list of improvements. The real crime is that it's taken MS 20 years to get their act together and make them awesome. Thanks for the great work Nick!
These feature videos are amazing !
I'm sure that not many people know that Kotlin has had those features for a very long time. It's such an underrated programming language...
It is right, something I feel like 'omg another possible interview question I should learn' but this particular feature looks handy.
This definitely makes the language a bit more complicated again... but I think this is totally worth it.
Boilerplate is the bane of larger software projects and if they're gonna have properties as a language feature for abstraction then it makes sense that they'd go all the way with making them as concise as possible.
Especially in WPF Projects that heavily depend on the INotifyPropertyChanged interface this will be a godsend. Good stuff.
Every single adjustment makes the language more complicated, I hate seeing this "argument" everywhere. Complicating the language further is not a deal, as long as the design is well-defined, looks clean and fitting, and works seamlessly.
@@AlFasGD great take, also people make the point that it will be harder for beginners, but I disagree. I came from c++ for me it was a complete mindfuck but eventually you start loving the power of the language and really c# magic is not complicated. But it was very unclear that a property is a pair of functions pointing to a field.
The main difference between C++ and C# is that C# has more concepts fundamentally built into it from the very beginning, allowing it to expand further without much interference. C++ has adopted several strange symbol combinations that make it even harder to import new features, and the syntax that is being reserved becomes increasingly more obscene.
Yesss finally. I think i've been crying about this for a year now.
OnPropertyChanged is right on spot! Was waiting for it for so long to get rid of backing fields
So siked for this! Was bummed when it dropped from c#10, so glad it made it in now.
Cool stuff. I wish they added it from the very first version, cause now we have 10 ways to define a property
Very usefull. Like others say: feels like something we already wanted for a long time. It's too often that small amounts of logic, for example the OnPropertyChanged()-thing, are needed. And in such a case it always feels as a waste to also need to add the whole other ceremony with the backing field.
Furthermore I am also VERY happy that they did not force the underscore-fieldname notation as an automatic thing, but that they came up with just a keyword which has always the same.
Most important thing here is that I am not particulary happy with the whole underscore usage at all for backing fields that many (most?) people do today (including Microsoft guys themselves), but not everyone (others, including me, have learned to prefer this-notation), while it kind of violates earlier guideliness in the past from Microsoft as well (to never prefix things, doing so was always considered a bad practice). So hopefully it kinda ends the need for that debate as well.
I was sceptical about another "new feature" but this one seems reasonable good and intuitively makes sense.
Yes, been waiting for this one.
I love it, now my wish for extension properties / events is all that is left in my wishlist
Heeey C# finally gets the "field" soft-keyword! No more fiddling with underscore-prefixed duplicates! That's great news.
What I like about these features is that they are very optional. You can do it all manually if you want and these are unlikely to ever get in your way if you don’t want to use them. So I’m not concerned about the language becoming bloated. However, it’s good that we have videos like yours explaining how they work. It took me ages to understand the difference between a property and a field
Thank you, Nick for this awesome content!
We love it.
Anything that allows me to write LESS CODE would be considered a win. I love condensed code that can be crushed to a single line. This is probably why I loved Lambda expressions when they first came out. Thanks for the update! Can't wait to "wow" my coworkers. :-)
This is definitely something people gona use. We were waiting for something like this.
this is something i wanted to have a time ago. it's nice they're implementing this
I always wondered why Properties needed the attribute declaration, finally they made it possible to get rid of attributes when working with properties
They are great options to have.
This is so great. I love the .NET team
Incredible feature!
This feature is great! 🙏
I really think it is a very helpful short way of doing properties. However, it will be rarely used as we most of the time use simple properties but it is nice to still have the option in cases needed
this looks awesome, finally!
Nick will be most famous youtuber in this domain in 5 years.
all great moves in my opinion. and clean
I love all these future fatures. I don't think having more and more features is a bad thing for C#. Everyone can choose to use them or not, but I think it brings value to a lot of people.
Great feature and yes this is so spot on. I have too much stuff on a virtual prop that is just a lambda getter to a semi expensive function. Adding this as a feature is a godsend. On top of that I honestly think there should be a prop keyword for just default get set, props are needed a lot of the time for various reasons and it would be way more clean.
Love this. I hate having to create backing fields that should only be accessed by a property yet are still visible to the entire class.
You can do the lazily initialized expression bodied property thing already, although you need to use a backing field. At first blush, needing to create an extra method feels less evil than needing to create an extra field, since you can't mutate the method like you can the field (although the method itself could mutate state, ugh). That said,
public string FullName => field ??= new Func(() => "nick chapsas").Invoke();
is possible, which finally encapsulates everything except the actual output of the property from the rest of the class. The syntax is rather unfortunate, however.
Edit:
A better way to do multi-line lazy getter-only auto property initialization is to ditch the expression bodied access altogether and just put all the logic in the getter. Eg:
public string FullName
{
get
{
if (field != null) return field;
var expensiveStuff = "nick chapsas";
return field = expensiveStuff;
}
}
love the content you make, keep it up.
I was needing the field keyword when I implemented my database so that users wouldn't need to write so much boiler, I ultimately redesigned my database but this definitely would've made the implementation work.
Very informative, thanks!
I love all these recent C# improvements. It's going to take me a while to learn them all and get used to them but a lot of them, especially with properties address things that have always annoyed me. I work with a lot of new technologies all the time so I constantly have to learn any evolve anyway. I just have to catch up with it all in the near future.
I really like this feature, it also gives you the option to pass an auto property by ref (sort of) if you just cache the backing field value and pass it's reference.
Is that supported? I mean, it should, but I don't know if it is (haven't checked). You'd do
public ref AddressStruct
{
get => ref field;
}
@@phizc No because the a property can't be a ref. You would just be able to pass the reference to something that cares about it on the getter or setter. It has limited uses but is something you wouldn't have been able to do without first creating your own backing field.
@@bambosa4952 I know that you need a backing field, and since the 'field' keyword is a way to get the backing field of the auto property, that'd be how you'd get the reference of the backing field.
I just tested it in sharplab. It doesn't work, but that's because it creates a readonly backing field. That might be improved I think.
Edit: ignore that I made the Addr struct a record struct. Bad example since it's immutable. I wrote it that way since I'm a phone and it's shorter..
Anyway, this works:
public record struct Addr( string Street, string City);
Addr _Address;
public ref Addr Address => ref _Addr;
@@phizc Awesome, that's interesting and good to know. Also you could stop the field being readonly by providing a setter on your property. A get only auto property or one with init only setter will provide a readonly backing field.
@@bambosa4952 unfortunately not.. ref properties can't have setters.
I am embracing each one of the new C# features. I haven't learnt them all yet but I will. I don't think it's right thing to point to new features and say "do we have to learn all these stuff?". If I am not able to learn some new features of the main language I am using to earn my living, maybe I should consider another profession. Each one of them are to make our lives easier.
Damn this is so good, FINALLY.
Regarding more keywords: as long as they're context sensitive it doesn't matter. Counter-example: in/out. You can't have variables with these names because they're keywords, but the keywords can only be used in specific places such as a modifier for method arguments and generic arguments, so they should not be treated as keywords anywhere else.
Edit: I'm guessing that field will be a context sensitive keyword and only be treated as such in properties. Like "value". You can use that as a variable name or argument even though it is a keyword in properties.
Regarding more ways of doing things that you need to keep track of:
You really don't. You can keep using any of the old ways. Nothing is forcing you to use any new features. Only if you encounter it in somebody else's code would you have to understand it, and it looks quite self explanatory, and if not there's Google.
This is a great feature, was kind of forced into restructuring for lazy initialization for some expensive DB requests, this will make it a bit simpler for the next person reading it.
as long as you can write it like you used to, it's all good.
shorter than Lazy thats for sure!
When you are working with C# and Kotlin at the same time and it seems fanny comparing:
1. C# approach will come soon:
public string SomeLazyProp => fields ??= SomeHardStuff();
public string SomeHardStuff() { return "Something"; }
And
2. Kotlin approach already exists:
val someLazyProp: String lazy { "Something" }
C# is a great language and I love it but sometimes he can spy on others
Oh that’s awesome
Nice! In eight years from now maybe schools will use it too
I like it.
I want easy, baked-in reactivity, though 😉
Did they decide to delay this feature? I can't see it in any "coming in c# 11" articles.
in the trasnlator
how can you call a variable name with these:""
i.e.
string k__BackingField
As long as new features solves a problem or makes code shorter and more expressive, I would call it the opposite of bloat.
whoever complains about it, just do it the old way. its a feature to provide shortcuts, to write things faster and cleaner. its not a obligation to use it.
as long as the new feature is idiomatic, i'm fine with it. you can intuit what `field` does in both property get/set and lazy contexts do.
similarly you could intuit what the argument can't be null syntax was doing.
How does he get that compiled code view to the right? Anyone have a video on that? It seems super useful for beginners.
How is 3:45 valid code in C# 11?
There is a backing field _fullname and the compiler does kinda know about it because of the setter, but he can't simply infer it from the setter in more complicated cases, because there could be multiple or more complex "backing fields".
For example the following:
private int _year;
private int _month;
private int _day;
public DateTime Date
{
get;
set
{
(_year, _month, _day) = (value.Year, value.Month, value.Day); //or something along the line if I made a mistake here, you get the idea
}
}
What would the compiler assume as the backing field? How would it handle such cases?
Other than that, I do like the field keyword.
The compiler generated backing field is always the same type as the property. Ignore the one I explicitly specified, I just didn’t delete it yet at that point in the video. In your example your setter will use custom fields but the getter still points to the DateTime generated backing field
@@nickchapsas ah, so the setter will assign to the keyword "field", which explains how the getter knows about that field.
As far as I know you can write
string prop {get;} = ComputingVal();
To have the exact behavior but with much cleaner code, also just a little bit faster
No that's not valid C# code. It only works for static members, which makes it very nieche. Non static members cannot be used with that syntax
With the OnPropertyChanged example, often the implementation uses [CallerMemberName] or a string. Would nameof(field) give you FullName or would it be the backing field?
CallerMemberName should work as normal. If it's called in a property, then it's the name of the property that gets passed.
nameof(field) doesn't seem to be allowed at all. Makes sense since generated fields have unspeakable names anyway.
Does the `InefficientStuff` needs to be static?
What would happen many threads invoked the getter at the same time?
thats likable
Was this finally implemented? I can't get it to work in VS17.4.0 preview 2.1 targeting net7. The field keyword does not compile for me.
The feature was pushed to C# 12.
New features are actually useful, the problem is in real world scenarios is not easy to just drop support to old runtimes and embrace these new features. and/or it’s not easy/feasible/possible to #if NETVERSION and take advantage of them. What do you usually do in that case? I’m currently supporting .net45 and everything in between through net60 in my projects
I wish they had started with a complete, coherent design for classes, constructors, fields and properties - every new feature solves for one particular problem and adds more complexity, more choices, more pros and cons you have to weigh for every addition to your codebase, more inconsistencies among codebases, and more time wasted debating, reviewing opinionated pull requests for alignment with your personal code standards and unimportant details. Simply put, it's already more complex than it should have been. But even then, many things still feel rough - like for one, still having to add boilerplate constructors for simple models. I can't even honestly suggest a way out of this situation, because much of the inherent language complexity is in the actual VM and runtime. Deprecations maybe? But of course you'd still need to come up with a complete and coherent design that is backwards compatible with existing syntax. I'm afraid it's too late for C# to dig itself out of the hole it's in. It's an okay language, as it is - but much like PHP, I think it's too late for it to ever become a great language. At some point, all you can do (short of starting over) is to step on things, and step harder, and eventually everything ends up bent out of shape.
Perhaps something like Kotlin for C# could get this language out of it's rut? Of course that's still like starting over, in a sense. But maybe that's what's needed. A new syntax with a simple, complete, coherent, more opinionated design? Similar semantics, better ergonomics, stricter type checking, etc... It's a lot of work though - perhaps even more work than just building an entirely new language... 🤷♂️
Is that “lazy assignment” thread-safe?
People that worry about too many changing features in c# haven't worked with CSS.
omg FINALLY
Neat!
Is this available in Visual Studio?
I like it
In general, I don't think you really have to keep in mind all the new ways to do things, as thankfully, your IDE, Resharper or whatever will remind you when you forget.
Is that lazy init thread safe? Meaning can two separate threads invoke the InefficientStuff() method if they happen to be triggered at the same time, or is there sam built-in lock in the null check + assignement?
I assume it's not thread safe, but I'm not sure.
Had the same thoughts. Looks nice but I doubt it being thread safe.
That part isn't new, it's just short for:
field = field ?? InefficientMethod();
which sets field to the method return value if field is null, otherwise it sets field equal to itself. The only new C# 11 part is that 'field' refers to the backing field of the property. Hence I can say with confidence that it is *not* thread-safe, sorry!
It is not thread safe no. You can make it thread safe by wrapping it in Lazy
Well, there isn't really a reason for people to get angry at this. It is just syntax sugar. You are not losing performance for not remembering this, just convenience.
Aww hell yeah
I had no idea that field thing for attributes existed and that’s interesting! Definitely some use cases i can think of with that.
Are there any other ‘attribute specifiers’ that i should know about? I know there is the ‘assembly’ and ‘module’.
'return' is one. It affects the return value of a method.
I run into these situations all the time so I'll use it regularly. Really a shame it wasn't in the language years ago.
Hmm I don't know.. I never use properties like that. Well I avoid having rong running things there. A property should just be a quick way to get a value as currently is in memory or set it. Some lookup or quick calculation is fine, of course, but getting or setting things in a data base or calling a remote instance from your property is terribly bad imo. Because most of the time reading a code base you assume this expression 'var something = object.Property;' you'd expect something to be assigned what ever Property has at the moment, not that this property will start calling remote code or something. Then you have to start double checking all the properties if they also do this. Compare to this' var something = repo.GetAllSomething();'
But I don't know, it's just one feature, I would like to know if you can see the whole design doc or some design goal overall, like what is the goal of the language in 5 or 10 years. Now I just get the feeling they just want to get in popular things as they pop up here and there.. It kind of feels a little desperate and short sighted so there fore I would like to see if there is actually a long term plan for all these features
Am I missing something, or is there the possibility of unexpected results? I call the prop to get a field from a function that is calculated the first time, but subsequently it returns only that value ... but later the underlying function that returned the initial value returns something else.... ?
Great feature! It was really annoying to put logic in properties because of the boilerplate code.
I'd rather have the tool and not use it than need it and not have it.
How to enable this feature? With net8.0 and languageversion set to 12.0 there is still no magic. (Visual Studio 17.8)
Still not implemented?
you can't enable it. Microsoft did not implement it yet
It will be available in C# 13
I will definitely use this…. When unity supports C# 11
I don't mind the "field" keyword, I can goggle that. It's shortcuts like ??= what bothers me, because if I don't already know what it is, I can't google it and learn it :)
The ,,field'' keyword feature is great, it will make the code a lot cleaner, but something seems off with the ,,??=" keyword. I think that logic like that should be more verbose, but mayby it's just my habit
Okay, excluding the field keyword, I've already used many times ??= Keyword. It's not a new thing. I don't know if it works differently now, but the syntax itself was valid before
Never said it wasn't. You just no longer need an explicitly defined backing field anymore
C# seems more scary every single day
I love this feature and I'm glad they went with "field" instead of an underscore, which is a gripe I have with switch expressions.
but is the new lazy way to set initial value thread safe?
Everything they do to make writing code easier makes reading code more complex.
The problem with bloat isnt that theres more stuff but that there's more stuff that doesn't bring anything new or worst case scenario makes code longer or less legible. The reason why c++ bloat is bad is because the features seem like an afterthought where as here it's fully integrated.