@Stysner It makes your code look much tidier, by not making you check against null values at all. And since you have control over your code and know how it is supposed to work and what to return, it's also less error prone.
I think nullable reference types should have an additional option to add the null reference checks to the beginning of every method, unless an argument is nullable. For people that implement guards, we use it everywhere, and it's the exception when we don't. That's why the !! Operator was bad, because we would have had to litter our codebase with it.
Its an interesting approach, but i prefer nullable because it is just so elegant. It allows you to write your code in a way that null exceptions never happen so there is no need to check for null at all (which also removes guard statements from your code)
Personally I prefer a functional approach to this -- essentially a much more explicit management of nulls with a monadic sum type like Maybe (Option), Result / Try, Either, ... Explicit and / or unmanaged returns of a null in a codebase is IMO a code smell; and I similarly would categorize the more terse !! operator as part of that problematic camp. Also in context of this video; I similarly don't find the NullGuard project to be a significant improvement over either the default state or the previously proposed !! operator. In addition I rather prefer the notion of earlier returns, as in, for example: Swift's guard statement (inverted if clause) to accommodate earlier throws... similarly the used of Kotlin's Elvis operator and C# ?? operator for a similar purpose to Swift's guard statement.
In C# system intern structs have a instance without being created. Does anyone know how I can make this with my own structs. I don't find any documentation about it
Great video, great library. I've used Fody's INotifyPropertyChanged library and it was magical. However, I can't help but wonder if there are any performance impacts whatsoever (e.g. using reflection at runtime to check for the NotNull attribute), or is this essentially a source generator that writes the same type of null checking that you would have written manually.
I rather have nullable reference types than use a magical code weaver in this case. Why? Because having and using nulls should be a language level feature, a feature that is static, can be expressed in code and is expected, explicit. What if someone doesn't know that you have that weaver in your codebase? Good library, but seems like an effort made before something more standardized could be developed and included in the platform.
This works on top of NRTs. It’s not one or the other. NRTs doesn’t mean that a non nullable type can’t ever be null. It’s complimentary rather than a replacement
@@nickchapsas I see. So it basically throws null reference exceptions for you when you forget to check for nulls, even if you use NRTs. Seems so redundant to me. I still stand by my words before. It should be a language level feature to guarantee non-nullability, a static compile-time feature, not a runtime check. Alas, this is it seems the only viable current solution. But I still dislike having to handle exceptions that *** should not happen *** in the first place. 😩
When you say about turning the nullables into errors do you mean just enabling both nullable and treat warnings as errors in the csproj or is there another way?
Usualy I create a Directory.Build.props file with CS8600;CS8602;CS8603;CS8604;CS8625;CS8618;CS8620;CS0219 the props file is used for every project in the folder
It’s actually not. Even if you have nullable on, you can still get nulls in those values because NRTs are just a compilation thing, not a runtime thing, and it’s not guaranteed
It’s the “Essentials bundle” that only has the two together because I consider them essential. The minimal APIs one is separate because it’s situational
Cannot imagine situation in which normal null check could become a problem. But instead, using such 'approaches' could make typical developer's life a nightmare. It's kind ..hey, why we are still using a door to get into a car? 21 century, lets use a window for that. One more...program writing is not a painting making. Your programs must be readable and understandable longer then a few months.
Honestly, adding Nuget packages for every little thing is, IMO, a bad programming habit that should not be encouraged because it might cause problems if not today sometime in the future. I'd much prefer to have the bang-bang operator straight into the language itself than adding a thousand Nuget packages in my project that might stop working or become not supported in the near or far future. In my 30 years career as a software developer (i begun programming in BASIC on an MSX, before DOS became largely used on home computers) i saw way too many "cool things" (or even whole programming languages) just disappear or being abandoned or superseded by the next cool thing and i know how many troubles this can cause when trying to improve, update or fix an old software that uses such packages/features. In my opinion you should ONLY use well established, well known, largely adopted and well supported packages/components and even then, do that sparingly. Every time you add a dependency you risk to find yourself in 5 or 10 years to have to update an old software you made (and barely remember) and find that the cool little package you have used is not available anymore for the new version of your IDE, language or framework... and, sometimes, you don't even remember what it was used for and what was its purpose.
It would be perfect if this doesn't create any additional files in project. I don't really mind this xml file, but if we accept that this is fine for a library to have such xml files, then we will be drown in useless configurations laying everywhere in a project and begin ultimately garbage.
I partially share your enthusiasm in having your code seem to look cleaner. At the same time this enthusiasm leads to a fallacy in showing how-its-done to inexperienced coders, since they tend to rely more on hidden magic, imho out of the same reasons that children like fairy tales. Magic elements, no matter their origin, have a tendency to becoming a pitfall. Try not to violate the principle of least astonishment. Have someone code with this library for a year as a beginner and he will 'know' that and 'only that' there is no null checking required or involved, no decision to be made on tell-don't-ask-coding, no input parameter checking and so on. Give this lib to a cobwoy coder and he will re-write his code for demonstrating even more elitist geekiness. Like Jeff Atwood mentioned, most developers have an unnatural knee-jerk tendency to rewrite for the sake of rewriting. Think about it like that: Try to write a book using any language without understanding rules and grammar, will you succeed? Well, it depends, because your story telling is more important and something quite different. You need pathos, ethos and logos, but you also need facts, definition, quality and relevance. Code is meant to be written for other coders to understand, not for the machines and not for your 'own' beauty standard. Omit essentials = omit fundamental understanding. Less code is not meant in a way to hide LoC.
You don’t need to disable null checking. It works with it. NREs are just compilation bars but they can still get nulls. With this approach you can’t get any
I’m late to the party and I just discovered: if (thing?.NestedThing?.DeeperNestedThing is DeeperNestedClass thingIWant)… I had no idea it’s been there since 2015!
Good morning Nick, it's everybody. Just checked the comments for null and returned true, submitting this ticket as a big fix right now
Greatest version of "first" I've ever seen
If you like these types of comments, and you want to see more...
I would love to see an in depth video about csprojand nuget packaging :)
This is great combined with NRT. A built in option to enforce non nullable types at runtime would be awesome!
That's really how I wanted NRT to work out of the box. I am still not sure why they could not add a compiler flag, e.g. strict-enable, that does this.
I like nullable enabled, always use it in the new projects with combination with errors
@Stysner It makes your code look much tidier, by not making you check against null values at all. And since you have control over your code and know how it is supposed to work and what to return, it's also less error prone.
Cool! And I've also learned about assembly weaving.
I think nullable reference types should have an additional option to add the null reference checks to the beginning of every method, unless an argument is nullable.
For people that implement guards, we use it everywhere, and it's the exception when we don't. That's why the !! Operator was bad, because we would have had to litter our codebase with it.
Your channel is a great reference
Nice. Fody helped me so much ;)
Fody is awesome, but it also might be confusing magic for some.
Expanding our knowledge is always good. It is a very simply but powerful introduction to assembly weaving
Its an interesting approach, but i prefer nullable because it is just so elegant. It allows you to write your code in a way that null exceptions never happen so there is no need to check for null at all (which also removes guard statements from your code)
The problem is that nullable alone can still have null values even if they are not nullable so keep in mind
Personally I prefer a functional approach to this -- essentially a much more explicit management of nulls with a monadic sum type like Maybe (Option), Result / Try, Either, ...
Explicit and / or unmanaged returns of a null in a codebase is IMO a code smell; and I similarly would categorize the more terse !! operator as part of that problematic camp. Also in context of this video; I similarly don't find the NullGuard project to be a significant improvement over either the default state or the previously proposed !! operator.
In addition I rather prefer the notion of earlier returns, as in, for example: Swift's guard statement (inverted if clause) to accommodate earlier throws... similarly the used of Kotlin's Elvis operator and C# ?? operator for a similar purpose to Swift's guard statement.
Currently fixing 1000ths of warnings in our codebase of which most are null reference related (nullable reference types enabled ofcourse)
I think Source Generator feature would be really useful in this scenario
In C# system intern structs have a instance without being created. Does anyone know how I can make this with my own structs. I don't find any documentation about it
Great video, great library. I've used Fody's INotifyPropertyChanged library and it was magical.
However, I can't help but wonder if there are any performance impacts whatsoever (e.g. using reflection at runtime to check for the NotNull attribute), or is this essentially a source generator that writes the same type of null checking that you would have written manually.
There is no reflection. It actually emits code in compile time and it acts as if you had the code in place. It’s very performant
@@nickchapsas What code editor are you using? I don't recognize it.
@@AdamsTaiwan It's called JetBrains Rider
Hey Nick, how to create account on your website to get the course? There is only login btn. :(
"null... nullable.... NULL ABLE"
I rather have nullable reference types than use a magical code weaver in this case. Why? Because having and using nulls should be a language level feature, a feature that is static, can be expressed in code and is expected, explicit. What if someone doesn't know that you have that weaver in your codebase? Good library, but seems like an effort made before something more standardized could be developed and included in the platform.
This works on top of NRTs. It’s not one or the other. NRTs doesn’t mean that a non nullable type can’t ever be null. It’s complimentary rather than a replacement
@@nickchapsas I see. So it basically throws null reference exceptions for you when you forget to check for nulls, even if you use NRTs. Seems so redundant to me. I still stand by my words before. It should be a language level feature to guarantee non-nullability, a static compile-time feature, not a runtime check. Alas, this is it seems the only viable current solution. But I still dislike having to handle exceptions that *** should not happen *** in the first place. 😩
When you say about turning the nullables into errors do you mean just enabling both nullable and treat warnings as errors in the csproj or is there another way?
Turning NRTs on and treating that specific warning as error yeah
You can treat all nullable related warning as errors by adding this to your project file.
Nullable
Usualy I create a Directory.Build.props file with CS8600;CS8602;CS8603;CS8604;CS8625;CS8618;CS8620;CS0219
the props file is used for every project in the folder
@@lucasteles42 Any reason for specifying the warnings explicitly?
@@MiningForPies You missed my point but that's fine. I figured out the answer to my question by myself :)
I just have nullable always on so this and that banbang was useless...
It’s actually not. Even if you have nullable on, you can still get nulls in those values because NRTs are just a compilation thing, not a runtime thing, and it’s not guaranteed
You don't need to pass nameof() to .ThrowIfNull() btw
Yep. It uses [CallerArgumentExpression] behind the scenes, which is also a useful thing to know about independently.
Good point, I forgot it was using the caller argument expression internally
Does "From Zero to Hero" consist of two components (DI and unit-testing) only?
It’s the “Essentials bundle” that only has the two together because I consider them essential. The minimal APIs one is separate because it’s situational
@@nickchapsas Thanks.
Keep in mind that fody is not free and expects you to be a patron
Although you can still use it for free, expect no help from them (even your PRs will get rejected) if you're not a patron.
It sucks really.
I mention it in the video
@@guiorgy well I’m not using the project 😂
Cannot imagine situation in which normal null check could become a problem. But instead, using such 'approaches' could make typical developer's life a nightmare. It's kind ..hey, why we are still using a door to get into a car? 21 century, lets use a window for that.
One more...program writing is not a painting making. Your programs must be readable and understandable longer then a few months.
Checking for null without checking for null. So it has come the full circle
Honestly, adding Nuget packages for every little thing is, IMO, a bad programming habit that should not be encouraged because it might cause problems if not today sometime in the future.
I'd much prefer to have the bang-bang operator straight into the language itself than adding a thousand Nuget packages in my project that might stop working or become not supported in the near or far future.
In my 30 years career as a software developer (i begun programming in BASIC on an MSX, before DOS became largely used on home computers) i saw way too many "cool things" (or even whole programming languages) just disappear or being abandoned or superseded by the next cool thing and i know how many troubles this can cause when trying to improve, update or fix an old software that uses such packages/features.
In my opinion you should ONLY use well established, well known, largely adopted and well supported packages/components and even then, do that sparingly. Every time you add a dependency you risk to find yourself in 5 or 10 years to have to update an old software you made (and barely remember) and find that the cool little package you have used is not available anymore for the new version of your IDE, language or framework... and, sometimes, you don't even remember what it was used for and what was its purpose.
Fody is a established set of projects with a very well known developer behind them. The platform has 80 million downloads behind it
It would be perfect if this doesn't create any additional files in project. I don't really mind this xml file, but if we accept that this is fine for a library to have such xml files, then we will be drown in useless configurations laying everywhere in a project and begin ultimately garbage.
IL weaving feels like a dirty thing to do...
The biggest problem with it is that it’s not extremely obvious so people looking at the code or debugging it might get really confused
Sadly fody expects you to pay for it.. So it's opensourceish..
I partially share your enthusiasm in having your code seem to look cleaner. At the same time this enthusiasm leads to a fallacy in showing how-its-done to inexperienced coders, since they tend to rely more on hidden magic, imho out of the same reasons that children like fairy tales. Magic elements, no matter their origin, have a tendency to becoming a pitfall. Try not to violate the principle of least astonishment. Have someone code with this library for a year as a beginner and he will 'know' that and 'only that' there is no null checking required or involved, no decision to be made on tell-don't-ask-coding, no input parameter checking and so on. Give this lib to a cobwoy coder and he will re-write his code for demonstrating even more elitist geekiness. Like Jeff Atwood mentioned, most developers have an unnatural knee-jerk tendency to rewrite for the sake of rewriting. Think about it like that: Try to write a book using any language without understanding rules and grammar, will you succeed? Well, it depends, because your story telling is more important and something quite different. You need pathos, ethos and logos, but you also need facts, definition, quality and relevance. Code is meant to be written for other coders to understand, not for the machines and not for your 'own' beauty standard. Omit essentials = omit fundamental understanding. Less code is not meant in a way to hide LoC.
I mean I'm not using this and it's not something I would use myself but there might be someone that thinks this is good for their project
It is not the most popular intent of videos where you show not popular nuget packages with not the best solutions.
I need to disable nullable checking? No thanks, I prefer compilation-time checking instead of ArgumentNullExceptions.
You don’t need to disable null checking. It works with it. NREs are just compilation bars but they can still get nulls. With this approach you can’t get any
First
I’m late to the party and I just discovered:
if (thing?.NestedThing?.DeeperNestedThing is DeeperNestedClass thingIWant)…
I had no idea it’s been there since 2015!