Should you stop returning "null"? | Functional C#

  Рет қаралды 104,531

Nick Chapsas

Nick Chapsas

3 жыл бұрын

Become a Patreon and get source code access: / nickchapsas
Check out my courses: dometrain.com
Hello everybody I'm Nick and in this video I wanna talk about how we can leverage a functional concept in C# that can potentially help up eliminate unexpected errors in our system. I am talking about null and the hundreds of issues that I have personally experienced with it over the year. Let's take a look at the problem and discuss a potential solution.
Give Language Ext a star: github.com/louthy/language-ext
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
#dotnet #csharp #functional

Пікірлер: 280
@JayVal90
@JayVal90 3 жыл бұрын
I think it’s much easier to just use C# nullability syntax.
@r.c8756
@r.c8756 3 жыл бұрын
Well, quality of code sure has a cost...
@SamFerree
@SamFerree 3 жыл бұрын
With the vast amount of the BCL that was null annotated in net5 and if you treat warnings as errors (which you should) then yeah. NRT is now the a fitting, and more idiomatic c# solution.
@Luturol
@Luturol 3 жыл бұрын
even tho u have to check if has value in some cases
@mahmoudalsayed1138
@mahmoudalsayed1138 3 жыл бұрын
@@Luturol You could mark it as non Nullable reference type and throw null exception in the method, outside the method you will be 100% sure it can't be null, ergo, there is no need to check fo nulls, there is no boilerplate code.
@mahmoudalsayed1138
@mahmoudalsayed1138 3 жыл бұрын
Exactly! Not much easier, it's way cleaner to the code.
@AlanDarkworld
@AlanDarkworld 3 жыл бұрын
An important topic right there. Null values in a langauge where the type system has no notion of "nullability", null values are a liability that you have to work around, e.g. vai Optionals. In a language which has the concept of a nullable type built right into the type system (such as Kotlin or TypeScript), null values become an asset. The compiler of such a language will actually refuse to compile a file by throwing a compile error at you if you try to do anything that *might* result in a NullPointerException. This has been revolutionary for my team and for my way of writing code. This feature alone makes Kotlin vastly superior to Java. It may seem like a small thing, but the impact it has is tremendous.
@olovjohansson4835
@olovjohansson4835 3 жыл бұрын
I like this pattern and we use it a lot. Otherwise an interface does not signal whether you should check the result for null or not - you have to read the documentation, or the implementation. Nullable referense types also solves that problem
@twiksify
@twiksify 3 жыл бұрын
I remember missing an equivalent of Maybe in Haskell years ago, but have since then forgotten why. Thanks for refreshing my memory!
@henrykkaufman1488
@henrykkaufman1488 2 жыл бұрын
Languages without null, like Rust, use exactly the same Opiton thingy. It does 3 things: - explicitly removes null from places it doesn't have to be (or would ever exist) - makes sure programmer is aware / handles the null case - makes programmer write more code Other than that, nothing changes. So generally it's safer code at cost of more code. I like these videos, they're pretty expert and unopinionated (professional). Thanks for doing this. I would love to see some material on possibilities of making sure a function won't change what you pass to it (like not passing mut in rust or using const & in c++).
@superpcstation
@superpcstation 3 жыл бұрын
Hi Nick, would really appreciate it if you could increase your font size a bit. Really helps out the mobile viewer.
@alfredoquintanalopez2265
@alfredoquintanalopez2265 3 жыл бұрын
Cool video, Please continue with this functional approach it's great!!!
@davidsaunders1595
@davidsaunders1595 3 жыл бұрын
Good for you doing a video on this Nick, I come from a Kotlin environment where null safety is a first class citizen and I was blown away how much of a game changer it was. IMO the C# world has been slow to adopt the trick properly. I will say C# 9 nullability syntax with warnings as errors is what we use for this now, skipped C# 8 cause it had awful collisions with nullable struct syntax and generics. If that’s not an option something similar can be achieved with ReSharper/Rider, JetBrains Annotations and Implicit Nullability if running static analysis checks is viable. Short of that though this is what I’d use, good job.
@nickchapsas
@nickchapsas 3 жыл бұрын
It’s one of the reasons why I love Kotlin so much. With C# it’s obviously an afterthought and it’s up to the user to adopt which is understandable but sad if it doesn’t get adopted widely
@goranstefanov4531
@goranstefanov4531 3 жыл бұрын
I like the idea. Prevents exceptions and it feels like a proper approach. I would definitely enjoy more videos like this. Thank you!
@TanigaDanae
@TanigaDanae 3 жыл бұрын
I think this is very subjective but a neat solution. Personally I like to use vanilla paradigma and since you have to rewrite all the interfaces and functions to use "Option" you end up with a "Get(...)" and a "Match(...)" function instead of your "null" check. In this specific case I could make the code "null" aware in other ways e.g. by implementing a "bool TryGet(..., out)" instead. But at this point I guess it is just a matter of taste.
@michaelgehling6742
@michaelgehling6742 2 жыл бұрын
I prefer the try-pattern with bool TryGetSomething(out SomeType result). I n this solution the decision making is also implied and I don't need any unnecessary lambdas.
@brianm.9451
@brianm.9451 2 жыл бұрын
I really like this approach. Wish I implemented it on a project since dealing with NULL’s was a huge pain for my app.
@sadux
@sadux 3 жыл бұрын
Great Chanel and tutorials. Thank you for sharing your knowledge. Keep going!
@DanteDeRuwe
@DanteDeRuwe 3 жыл бұрын
Thanks Nick for another insightful video
@Luturol
@Luturol 3 жыл бұрын
Great video! I was always wondering if C# had a similar to optional from Java
@dealstunner8317
@dealstunner8317 3 жыл бұрын
Perfect! Thanks for this video
@cs96ai
@cs96ai 2 жыл бұрын
Great video! Would be great for generating object model audit trail. Keep up the awesome work! Any plans to do Kubernetes, Swarm, rancher?
@WarrenLeggatt
@WarrenLeggatt 3 жыл бұрын
Null is not an issue, it is the lack of self documentation in the function signature public MyClass GetTheThing(); This function can return an instance, a null or throw an exception but you have no idea looking at the sig. This can mean people do not handle the possible outcomes. This is actually the correct signature such that just looking you can determine what can come back. public Either GetTheThing(); C# 8 with nullable reference rates part of the pain out as you know if its nullable. The more info devs have on what can come back the less risk of blow up when in production :)
@frotes
@frotes 3 жыл бұрын
Good stuff, I think functional programming patterns are great stuff that leads to cleaner and more expressive code, with less chance for bugs. C# is becoming more functional with every release. Would love to see more content in that direction on how to setup/utilize constructs like different monads and circuit breaker patterns.
@bernardoherrera5217
@bernardoherrera5217 2 жыл бұрын
I love functional programming, I programmed for more than one year in Scala then when I came back to C# 4 years ago I found that there weren't so many functional features built-in the language itself. But now the language it is envolving and that's a good thing
@the-matrix-has-you
@the-matrix-has-you 3 жыл бұрын
Tony Hoare has said "null was my billion dollar mistake" but I don't think he was right about that sentiment.The Programming World needed a Universal Type that reflects empty, has no members words in a simple way so we came Up with Nullable so that way any Type can be nullable the class looks for if the passed object is initialized or not and if initialized does it have a value set to it if yes then it is not null. So it was the Best way to do it really. Besides the whole .Net Framework Technologies depends on the Nullable Type there is no easy way of changing things now. I don't even mention the zillion of programs all around the World that is on production heavily depends on Nullable Type...
@SeanJMay
@SeanJMay 3 жыл бұрын
There are no safe operations on null, though. That is the difference. The world does need some Empty or Bottom type. That should not be a type whose default behaviour is to go kaboom, though. It's a type whose default behaviour should be a no-op, with a reminder to deal with the no-op, *without* encouraging people to just swallow catches, or return null to the next poor sap who needs to do the exact same things you just did... possibly without the same level of concern for soundness of the logical flow of the application.
@aurinator
@aurinator 2 жыл бұрын
Full Disclosure posting before watching video, but my initial reaction is that it isn't as long as that behavior is expected from whatever's returning null, as while I completely agree that it isn't necessarily optimal or desirable per se, I've seen it used to make variables effectively ternary values when null is used, and it worked very well, but it was similarly documented well enough that the behavior was expected. I'll update this after the video if my opinion changes. Thank you so much for explicitly touching on that there *WAS* indeed a way with Unsafe code though. Burying heads in the sand around those possibilities doesn't make them go away, but many have done it from my experience.
@bradenb
@bradenb 2 жыл бұрын
I love options, but I've had a hell of a time convincing my coworkers of their value. Occasionally I'll have some beautiful, elegant piece of code as a result of using them and they'll appreciate it, but never enough to try them for themselves. I've started sneaking options into common libraries to force it though :)
@jacobstamm
@jacobstamm 9 ай бұрын
It would be so cool to see a round table discussion between you, Zoran Horvat, and someone like Eric Lippert or Anders Hejlsberg discuss the merits of nullable types vs the Optional pattern in C#. There seems to be some degree of dogmatism around it and it would be nice to see that stripped away.
@MartinMaat
@MartinMaat 2 жыл бұрын
You need to see some code for this to make sense. I have had discussions about this on SESE and they went nowhere. It only gets meaningful at 9:45. Before that one can just go "So it won't blow up at the same point, it will continue to run in an undetermined state which is worse! You will have to check at some point, whether it be for null or None...". Obviously for fluent interfaces null is literally a show stopper, I got that. Now I also see the returned wrapper object forces you to obtain the (encapsulated) value in a safe way. This is the real boon that often gets lost in a focus on null itself.
@wordonice4457
@wordonice4457 3 жыл бұрын
Null for life!!! lol but this is quite nice. I'll check it out. Looks like the optional interface in Java, which I've used a lot
@TheExiledMeriler
@TheExiledMeriler 3 жыл бұрын
I prefer nullability. And I love how null safety implemented in kotlin
@nickchapsas
@nickchapsas 3 жыл бұрын
Yeah C# was basically trying to get to Kotlin's implementation with C# 8 but the problem is that null worked like this for so many years that it's been engraved to anyone's muscle memory and it's so hard to change your mind on something that you've been doing for years.
@BonBaisers
@BonBaisers 3 жыл бұрын
I use it on UI layer and Features layers (CQRS). Nulls and Exceptions are reserved to Infrastructure layer. Everything up must use Option like class type of response to force my devs to handle all cases on the application domain and the UI.
@bruceleggett7500
@bruceleggett7500 3 жыл бұрын
I agree that nulls are a multibillion dollar mistake due to finding null reference exceptions in the Production environment sometimes for edge case scenarios and other times deep within a property chain which takes some extra time to debug and resolve. The use of the generic Option class isn't the elegant solution I was expecting. I was expecting Options to be built into the language and complier itself and include extra option functions and syntax
@sonicbhoc
@sonicbhoc 2 жыл бұрын
That was one of the first things I noticed when I played around with F#. Option is built-in.
@recepdmr_
@recepdmr_ 3 жыл бұрын
Thanks for video. Integrasiting.
@alexanderhugestrand
@alexanderhugestrand 3 жыл бұрын
The only difference between returning null or to use "maybe", is that the latter gives you compiler assistance to enforce you to write that if/else statement that you would otherwise forget. Personally I think it's overengineering to use such a construct. If/else works just fine if you are disciplined enough and test your code before deployment.
@filipecotrimmelo7714
@filipecotrimmelo7714 3 жыл бұрын
I really like the idea. It prevents exceptions in the code, also leting new programmers doing less errors;
@amuuuinjured
@amuuuinjured 3 жыл бұрын
In that case - better way to prevent new programmers from doing errors is not allow them to code. :D
@filipecotrimmelo7714
@filipecotrimmelo7714 3 жыл бұрын
@@amuuuinjured LoL
@MoMadNU
@MoMadNU 3 жыл бұрын
Spend twice as much time testing than you do coding and it won't matter. Either you coded for null or you didn't and if you didn't it's a bug that you must fix.
@berylliosis5250
@berylliosis5250 2 жыл бұрын
@@MoMadNU Why waste time testing things the compiler can trivially verify for you? Test time is better than runtime, but compile time is better still. (Not to mention the more explicit/correct API)
@MoMadNU
@MoMadNU 2 жыл бұрын
@@berylliosis5250 The compiler cannot detect a null reference exception which represents 90% of the exceptions you will encounter because of bugs in your code.
@RicardoValero95
@RicardoValero95 3 жыл бұрын
Hi Nick, about your api route I've been having issues using guid type as a parameter (invalid guids return oks), but as I saw in your example you parse it in the controller. Is this the best way to do this?
@amuuuinjured
@amuuuinjured 3 жыл бұрын
1. What that code will look like when there will be two separate repository calls? Let's say get two different customers and return Ok only when both exists. 2. That library seems are over complicating things. If you need that Match method - write simple extensions method and check if value is not null call ok otherwise fail.
@arunbm123
@arunbm123 Жыл бұрын
brilliant, its clean way to return from Action Method
@kyoai
@kyoai 3 жыл бұрын
But if you try to actually access the returned optional object, you sooner or later still have to do a check whether the object is valid or "none", so essentially it did not solve the null check problem, you just shoved the validity check to another place and did it in a more fancy way.
@SamFerree
@SamFerree 3 жыл бұрын
If the only way to access the object is by "Match" then effectively you've compiler enforced the check, since you can't call Match for the Some only case, you MUST provide a None case or it will fail compilation. It moves the error from runtime to compile time. you can also do this post C# 8 by enabling Nullable reference types and treating all warnings as errors.
@r.c8756
@r.c8756 3 жыл бұрын
The point is not to remove the necessity of checking null values but to force the caller of a function to acknowledge the fact that it can return an empty value. This is mostly a safety/readability feature.
@rolandtennapel5058
@rolandtennapel5058 3 жыл бұрын
@@r.c8756 I read what you're saying but all I hear in my head is 'People are lazy in reading and writing documentation and have very dangerous assumptions.' 🤣 But seriously, developers that want to use this have had ways of doing this since day 1 of C# (me in part). Developers that don't want to use this won't (me in another part, bit of internally (protected) split on this issue). 😉
@atrumamantus
@atrumamantus 3 жыл бұрын
@@rolandtennapel5058 it's not about being lazy, missing a null check is a common bug even for seasoned developers. Having tools to help you keep your code sound is never a bad thing, and the possibility of trading a runtime error for a compile time error is always a plus. Java has Optional types as well and they are very useful.
@r.c8756
@r.c8756 3 жыл бұрын
@@rolandtennapel5058 Documentation will never replace code quality and yes, people are lazy. They sometimes make mistakes and sometimes, they even plainly suck. This is kind of a negative way of looking at things but on the other hand, making things safe is thinking of the worse that can happen and then think of a way to prevent it to happen. As a programmer, you should always assume that the next guys who’s gonna use your code will mess up in the worse possible way. (and if you have a bit of experience in the field, you know that this happen more often than you’d hope...). So an important part of our job is to write code in a way that they can’t.
@fuzzylilpeach6591
@fuzzylilpeach6591 3 жыл бұрын
"not null, just the idea of no value." Pretty sure that's what null is.
@icebird76
@icebird76 3 жыл бұрын
@Ishaan Jaxtyn Insane! It took me 5 minutes to say it worked!
@tofraley
@tofraley 2 жыл бұрын
You'd be incorrect. That's not what null is. The type system does not give us a way of representing "nothing" or "no value". So we use null to do that, even though it's problematic. And since everybody has treated it that way for so long, the compiler team had to create work-arounds so people would stop hurting themselves with it.
@coso2
@coso2 3 жыл бұрын
I still love use and return null :) But, from an execution perspective, which method is better on memory and execution speed?
@Kokujou5
@Kokujou5 2 жыл бұрын
wow... someone never saw C# colesce operators... outch... guess that hurts now^^ return customer ?? Notfound(); and this can be valid syntax because if your method is an ActionResult you can directly return T and it will be converted into an OK
@rolandtennapel5058
@rolandtennapel5058 3 жыл бұрын
Not for me, but I get it and I appreciate it 😏 I guess I'm just too comfortable with assuming anything / everything can be NULL and check for it (or pass by reference which helps a lot).
@masterdju1
@masterdju1 3 жыл бұрын
And its simpler to check if null... In thus case we need to use additional library and still write some checking code
@rolandtennapel5058
@rolandtennapel5058 3 жыл бұрын
@@willembeltman Checking inside the function means you don't have to remember to check outside the function. 😉
@CANEHURRICANE
@CANEHURRICANE 3 жыл бұрын
Cool stuff dude thanks
@argiziont
@argiziont 3 жыл бұрын
Wow, that's awsome solution.
@fullmoonyeah1180
@fullmoonyeah1180 2 жыл бұрын
at the end of the day, it depends on how the value is treated. it also has some benefits that developers can use with it.
@errrzarrr
@errrzarrr 3 жыл бұрын
I like the approach
@diegogarcia6518
@diegogarcia6518 2 жыл бұрын
I like this video, and it's a cool package; but my two cents are that NRT's were enough for most scenarios back when the video was released, and with the upcoming .NET 7, auto-implemented null checks will make it even more so. This further adds to boilerplate in recent versions, but if you're stuck with legacy, this package could be a god-sent
@samuelgrahame3617
@samuelgrahame3617 3 жыл бұрын
Use null if needed. Check for null. Or use not null option.
@fishzebra
@fishzebra 3 жыл бұрын
Thanks nice simple demo. I really like Option, however now C#8 has Nullable Reference Types there is less of a need for it. And as brilliant and extensive as the LanguageExt library is, it encourages C# developers to go deeper into using other Functional concepts which could easily confuse other team members and create unreadable code. Hopefully one day Option is built into C# and then we can freely use it, otherwise there is an argument that if you want to do real functional programming then you should stick to a Functional language like F#. I think this is valid, but it also frustrates me as there are not many F# jobs out there.
@javiermadueno
@javiermadueno 3 жыл бұрын
It would be nice to see a video using Option with async method
@nickchapsas
@nickchapsas 3 жыл бұрын
It would work in the exact same way. You'd just have to return Task.
@sidfjames1076
@sidfjames1076 10 ай бұрын
Since new null checking feature in dotnet, which can be set to an error, I think the issue with returning null is (pun intended) "null and void".
@leonardogoens9771
@leonardogoens9771 3 жыл бұрын
Nice one!
@JohnEBoldt
@JohnEBoldt 2 жыл бұрын
Update: I discovered the IfSome method which is exactly what I need for my use case. So no unsafe! I like this approach! I do have a use case question though. In my repository layer which uses EntityFramework, some columns are nullable and so if a property is null, I need to return a null value. I can do this using MatchUnsafe, but I'd prefer not to use it unless I have no other choice. Is there a better way to do this? Example: ExternalUserId is a string property in an EF table that is nullable in the database. ExternalUserId = user.ExternalUserId.Match(e => e, (string)null); This throws an exception when returning null. ExternalUserId = user.ExternalUserId.MatchUnsafe(e => e, (string)null); This works, but I'd prefer not to use it. Thoughts?
@GregWilliamBryant
@GregWilliamBryant 2 жыл бұрын
@Nick Chapsas - I would be curious to how you feel about this style in 2022. I've unconsciously implemented something very simular in my codebase and really like this style personally.
@zubairkhakwani8772
@zubairkhakwani8772 Жыл бұрын
If we have to operate on an object we're getting from DB, we still have to check for null before using it (In service or in the controller). So how does it benefit? I will still try it and see If it helps.
@aleksanderw5536
@aleksanderw5536 3 жыл бұрын
Hi, considering that C# has nullable types which if used can lead to eliminating null pointer exceptions as well, do you think that Option still has a place in there?
@nickchapsas
@nickchapsas 3 жыл бұрын
I do actually and I see them as a different thing. Nullable types and the compiler can lie and Jon Skeet has a great talk about that. It’s also to the library author’s discretion to use them. Option beats all that with a clean forced matching scenario
@ChrisWalshZX
@ChrisWalshZX 20 күн бұрын
Is there any inefficiencies introduced to using Option? You say it's a struct but there must be somewhere where a reference or a no-reference is indicated that doesn't occur with null and not null. The code is also more verbose than traditional use of null and compiler helping with Object? vs Object helps identify and remove bugs during dev. Not convienced yet but interested in your further forays into Functional Programming. Thanks Nick.
@albe8479
@albe8479 3 жыл бұрын
mindblown from the elegance of this syntax. Will try to implement it at work.
@JSDudeca
@JSDudeca 3 жыл бұрын
I would say yes but I don't code in C#. I always return some sort of "None" type reference. Does not matter what language I code in. For a strong typed returns like Java, I would subclass the return type to identify value like NullMap for returning a Map that is "None". Never done C# though.
@marsovac
@marsovac Жыл бұрын
I don't like this if I have it in the interfaces, because it makes the nuget a requirement for implementing them, and sometimes that is not allowed. So yeah, nice to remove "if (x!=null)" and convert it into something more explicit, as long as it does not have repercussions down the chain.
@vssrikanthgarnepudi5952
@vssrikanthgarnepudi5952 3 жыл бұрын
Hey nick can you please make a video on web api concurrency issues with an example .
@JonathanPeel
@JonathanPeel 2 жыл бұрын
I do like this (and I use F# a lot, so this makes a lot of sense), however, I think with the newer C# nullable `Customer?` I don't think it is needed. The language will force us to handle the case where the value is null. If we are handling a nullable, or we are handling an Option we are still handling it. I also like the idea of `map` and `bind` functions but we can also create those for Nullables just as easily as we can create them for Options.
@nickchapsas
@nickchapsas 2 жыл бұрын
It will only force you if you enable nullable reference types as errors in your project and even then you can ignore if you if think you know better than the compiler with the ! operator
@JonathanPeel
@JonathanPeel 2 жыл бұрын
@@nickchapsas Yes, that ! is true. I do that 😝 But usually, only in cases I know would have had an error a long time ago if what I am accessing is null. Maybe it proves your point. I have never seen the language extension library you talk about. I might check it out, although like I had said I use a lot of F#, so I might have a method returning FSharpOption or FSharpResult. This library probably wouldn't work on those.
@archstanton9182
@archstanton9182 2 жыл бұрын
My coding standard insisted that a function only has one return path. Multiple return paths can be confusing, especially if it is code you inherited from someone else who has left the company.
@morlock2200
@morlock2200 2 жыл бұрын
the only way i use null atm is if i got an method that i want too have 3 values where 1 might be null cause i only wanna use two, i prefer makeing an class where i can return a bool and a message(string) back and do stuff with that. so even if the return is null it means the bool check for if it´s true so if it returns as null it would run the "Failed" code and just say " it failed".
@fourZerglings
@fourZerglings 3 жыл бұрын
Should you stop returning null? Yes. Replace them with Optional.
@Ownage4lif31
@Ownage4lif31 3 жыл бұрын
Thought this was a joke, turns out you got a point. Thanks
@gleamofcolor
@gleamofcolor 3 жыл бұрын
Thanks for the video . why don't we add that option just before the return statement where we needed as I don't like the idea of changing the return type everywhere. If I want to share the logic between the module , how that works as it don't expose the object as it is.i need use some method in the option struct to get the retuning object value .it's unnecessary overload and performance issue as well.
@nickchapsas
@nickchapsas 3 жыл бұрын
Maybe this example doesn’t illustrate the point as well as I’d like it to because it’s a very simple example. Realistically you would have different return types on each layer and you wouldn’t just be able to return option itself. The whole point of option is that you cannot get the value without handling the None scenario and that needs to happen across your application. Also, like I said in a different comment, performance impact is negligible.
@gleamofcolor
@gleamofcolor 3 жыл бұрын
@@nickchapsas thanks, it would be great if you have another video which covers the said point.
@airjuri
@airjuri 3 жыл бұрын
@@nickchapsas "performance impact is negligible." Famous last words before performance issues commmence ;)
@nickchapsas
@nickchapsas 3 жыл бұрын
@@airjuri I can guarantee with 100% confidence that this will be the last thing that you will need to optimize in your application
@daneru
@daneru 2 жыл бұрын
For an API i would never use null return value. I'd return and object with some kind of warning message with 400 or 500 status code. So the recipient understands what happened. Also, the response is going to be handled differently because the status code is not OK. Inside assembly i think it is okay to use null. The key is to be consistent which is harder to reach working as a team.
@ronnyek4242
@ronnyek4242 2 жыл бұрын
Reminds me of rust and result types
@Rokannon
@Rokannon 3 жыл бұрын
2:35 Flag 'found' is redundant. You can just: _customers.TryGetValue(customerId, out var customer); return customer;
@UzairAli001
@UzairAli001 3 жыл бұрын
I appreciate the tutorial. I don't like the syntax that much, I prefer C# nullable over this. Of course this is my own opinion.
@nickchapsas
@nickchapsas 3 жыл бұрын
Hey Uzair, I really appreciate the comment. This is exactly why I make these videos. It doesn't need to be something that you will use but it's good to know that there is also this thing here that might be of use.
@UzairAli001
@UzairAli001 3 жыл бұрын
@@nickchapsas indeed exploring different options are definitely worth the time you never know when you might need that different approach. Keep it up 👍
@rhicanrong2494
@rhicanrong2494 3 жыл бұрын
I am looking for this too. I personally prefer using c# nullable between repository and services layers. But I think that option may serve better between services and controllers layers. It is great, Thanks for sharing.
@jasalvador
@jasalvador 3 жыл бұрын
Great video! But it's not almost the same on using c#8 Nullable reference types? I don't know how c#8 nullable exactly works, I think only throws a warning when compiling but actually it compiles. In that case, I agree with the use of Option. If we could make that the code does not compile, It would be right to use the nullable type right?
@nickchapsas
@nickchapsas 3 жыл бұрын
The thing with Nullable reference types is that it doesn't really prevent you from handling them. You can still use the bang operator (!) to suppress it and it's not an error until you explicitly mark it as one. It's basically an afterthought and realistically, people won't instantly jump into using it because they can get away without using it. Option is something that you need to acknowledge no matter what, which i prefer.
@mariacobretti
@mariacobretti 3 жыл бұрын
@@nickchapsas this is a very interesting discussion and maybe worth picking up in another video showing the approaches side by side with a more complex example. I'm currently leaning towards nullable reference types because I have seen code with pretty big classes and handling the matches made it quite difficult to read and understand. And with a good culture where you try to eliminate all the warnings I think its nice for a lot of cases. Also I just remembered that you can install the FxCop nuget package and have the null reference warnings pop up as errors instead so the project does not compile.. I probably should try that
@carlinhos10002
@carlinhos10002 3 жыл бұрын
You can configure the code to not compile if there are such warnings, and if one use ! forging operator, well, what he's saying is that "ok, I know it can be null but I don't care" which doesn't mean he forgot about null-check, pretty much the opposite. I think using yet another library to handle a case that's already done by the language is just too much. It was useful before c#8 but now it's just more complexity
2 жыл бұрын
I prefer not to return null when possible. I also try to avoid nullable value types.
@OldShoolGames
@OldShoolGames Жыл бұрын
What about throwing a custom exception and catching it at an upper level ?
@11r3start11
@11r3start11 3 жыл бұрын
I prefer to use functional syntax, its a lot more readable, though its harder to understand what's going on inside. But I'm wondering, how much overhead does Option usage have? especially .Match call with lambda-parameters
@nickchapsas
@nickchapsas 3 жыл бұрын
Very good question. It's my bad that I didn't cover it during the video. On this specific example: The Non-Option approach will execute at a mean time of 146 nanoseconds and will allocate 168 bytes of memory (it's probably the Guid object allocation). The Option approach will execute at a mean time of 222 nanoseconds and will allocate 296 bytes of memory (it's the Guid plus the Option object, even though this is stack memory allocation due to Option being a struct)
@WarrenLeggatt
@WarrenLeggatt 3 жыл бұрын
With the latest C#, if enabled, there is nullable reference types similar to int?. With this all reference types by default are not nullable which can mitigate much of this out and the time implications will be reduced. When you use nullable reference types you have the same .HasValue and .Value properties along with operators like ?? and .? Personally I have come around to null is evil. I have lost count of the null exception errors I have chased down over the decades I have done at the code face. It is far better to use this sort of technique to force devs to have to deal with the full types of the return value instead of mask it. If you get an Option or MyClass? returned you know you have the chance you have no value and are forced to handle it. If you just get MyClass returned without that protection you have no idea. It makes the function more explicit. Take the following public Result DoTheThing(); You can instantly see you might get a "good response" that might have a value or you get an error. No need to dig into the code to see if it can throw etc
@aborisov20
@aborisov20 3 жыл бұрын
I prefer always return IEnumerable even when just one object is expected. That solves the "returning null" issue. When no object found you will get empty collection.
@SamFerree
@SamFerree 3 жыл бұрын
Option is basically just a list of 0 or 1. Some implementations of option actually just extend IEnumerable and essentially just provide convenience methods for returning a list of 1 or 0
@r.c8756
@r.c8756 3 жыл бұрын
It works but it’s a (dirty) hack which damages the readability of your code. The very point of typing is to add meaning to otherwise completely abstract and decontextualized algorithms.
@aborisov20
@aborisov20 3 жыл бұрын
@@r.c8756 Disagree with the first sentence and agree with second sentence. :)
@r.c8756
@r.c8756 3 жыл бұрын
@@aborisov20 Returning an IEnumerable tells whoever read your code that they should expect several elements. This is deceitful and therefore, bad practice. Correct use of types, variable and method name should describe as accurately as possible their behavior... What do you disagree with exactly ?
@aborisov20
@aborisov20 3 жыл бұрын
@@r.c8756 Nothing related to term "dirty hack". Just expected behaviour. By design.
@ckjdinnj
@ckjdinnj 3 жыл бұрын
The options semantics is a bit obtuse. The exact same behavior is achievable in a clearer manner. The interface method should be changed from: Option Get(GUID id) ; To: bool TryGet(GUID id, out Customer customer); The first one has obfuscation that hurts more than it helps. TryGet signatures are clear and automatically enforced by proxy of out parameters requiring assignment by the compiler.
@ilove2learn783
@ilove2learn783 2 жыл бұрын
The best way to handle it is using exceptions. If you expect a value and you get null -> that's an exception to handle. Trying to work around it is just not worth it. Exception is explicit, caught in the code, easy to test, you can write your own and make it easy to find, you can return as many different exceptions as you wish at any time and add more as codebase grows. It's just too good to use anything else.
@nickchapsas
@nickchapsas 2 жыл бұрын
Exceptions should be exceptional. I am not a fan of taking a performance hit just to have an easy way out of the application's flow. It's convinient, sure, but it's by no means good.
@gardian06_85
@gardian06_85 3 жыл бұрын
I just get the feeling that if it is "none" then it has the form of the object, but could be uninitialized, and could kind of be more dangerous. if the code attempts to access an uninitialized field then it could lead to bad results, but if it tries to access null then it throws an exception. is it possible for a none to be modified into a real version of the struct/object. I just get the feeling that if it can be modified at any point then bad out of bounds data could cause bigger problems and maybe volnerabilities rather then the program hitting an Exception.nullReferenceException
@SeanJMay
@SeanJMay 3 жыл бұрын
These containers aren't for low-level operations, and aren't for async values (that last part isn't exactly true... *this* container isn't for async values... async/await itself hides the concept of containerizing requests), they're for code composition. At any point in your example, some programmer could have your instance mutated by 8 different threads at the same time, with no thread locks; how is null going to help you in that case? If that's how your team writes code, then nothing can save you. The class is already there and uninitialized, or poorly reconfigured. If my code needs to return an A, but in order to make an A, I need an x which I have, and a y which I don't, I can solve that in ways better than passing around uninitialized instances. async GetA () { x = GetLocalX(); potentialY = await GetY(); potentialA = potentialY.Map(y => new A(x, y), None); return potentialA; } I am only going to make an A in the case that I know I can correctly construct that instance. And what the next user gets is something that they can operate on (through Mapping from A -> B), Filtering from (A -> None) in the case they aren't interested in that instance, handling the case where they got nothing, or just passing it on to the next person down the line, who will do any or all of the above, before themselves passing it on. It benefits the system in general, to write it in such a way that you have no incomplete or ill-configured objects/structs/sets/etc floating around, regardless of what architecture you're using for code composition.
@tofraley
@tofraley 2 жыл бұрын
"None" does not have the form of the class you are trying to access. Lets say you have a method that returns an object of type Option. If you call that method, and it happens to return Some, you can think of that as wrapping a Person object. If you want to use that object, you kinda have to reach in and get it. In other words, you can't just treat the Option object like it's a Person object. On the other hand, if you call that method and it happens to return None, there is no Person object to access. In reality, that Option is probably wrapping a null Person object. But that's just an implementation detail, you have no way of accessing it. You can't accidentally access it. People in these comments seem to think the point is to have a clever way around null checking. That's not it. The point is to have a real representation of "no value" without bringing null into the equation at all.
@pateegutee7960
@pateegutee7960 2 жыл бұрын
How about using Null Object Pattern to avoid returning null?
@dcuccia
@dcuccia 3 жыл бұрын
C# 9 switch expressions are a nice built-in implementation of Match.
@logank.70
@logank.70 3 жыл бұрын
I use switch expressions all the time now. C# 9 makes writing functional code in C# much easier.
@ericfelipe2011
@ericfelipe2011 3 жыл бұрын
You do a simple IF in first code... But now, you generate a struct that consume memory and it's not a reference type, so, the object is copied in all return, plus you need two lambdas that's generate a lot of process and context keep process.... Why this is good ??? You need more memory, more process, more processor stack, and so on....
@nickchapsas
@nickchapsas 3 жыл бұрын
Because your code is safer. The benchmarks show a performance degradation in the class of a few nanoseconds for the benefit of NRE elimination and for predictable code. Ofc it’s something you can ship if you commit to using null reference types properly but again that’s up to the dev
@ericfelipe2011
@ericfelipe2011 3 жыл бұрын
@@nickchapsas if you put a check for null. Where the dangerous path of that ? Plus this nanosecond with a Friday, science software, bi software, financial software... And of course, change all your code... It's the basic of a language null treatment.... It's like... We are using a stable old fashion jeans... Let's create a radical new one.
@nickchapsas
@nickchapsas 3 жыл бұрын
@@ericfelipe2011 The dangerous part is that it's up to the developer to put the null check in. What you're assuming is that every nullable thing will be null checked at the right place, which is simply not true.
@ericfelipe2011
@ericfelipe2011 3 жыл бұрын
@@nickchapsas with new coalesce it's even simpler Return object?.property ?? New list() With so many code analítics, it's can be configured yo show a warning of a null reference or something.
@nickchapsas
@nickchapsas 3 жыл бұрын
@@ericfelipe2011 Coalesce is a completely different feature and has nothing to do with this. I agree that Null reference types can be configured to give a similar experience but it's still up to the developers and the team to enable it and make it mandatory (error instead of warning)
@masterdju1
@masterdju1 3 жыл бұрын
But whats wrong with null check? Why do we need to complicate code for a simple thing? In any case we should check if null or if match
@user-tk2jy8xr8b
@user-tk2jy8xr8b 2 жыл бұрын
You can avoid null check, but cannot avoid match
@iwan954
@iwan954 3 жыл бұрын
Rider has an option in refactoring to change signature automatically after changing implementation so you don't have to edit it manually. Very useful one, especially when you do some big refactoring.
@codex4046
@codex4046 3 жыл бұрын
Which is probably what he uses regularly, but for such a video other people might not get what is happening, doing it manually is better for explaining.
@zondaken
@zondaken 2 жыл бұрын
Whats so different between null awareness or none awareness?
@nickchapsas
@nickchapsas 2 жыл бұрын
null awareness is optional and can be skipped. Option is a discriminated union and it has to be handled no matter what. It's safer
@zondaken
@zondaken 2 жыл бұрын
@@nickchapsas you're referring to the second delegate? Uhh true i guess. Although you can pass null to that one as well but then you did it intentionally while null awareness can be forgotten. Yeah good point, got it.
@AngusMcIntyre
@AngusMcIntyre 3 жыл бұрын
We should really all be writing f# for our application and web tiers.
@phyberoptyk5619
@phyberoptyk5619 3 жыл бұрын
Good vid. This is the library we use: github.com/nlkl/Optional Same thing, different repo.
@Gastell0
@Gastell0 2 жыл бұрын
While it seems like generally a good idea, it's simply too late? C# has null so deeply rooted that it has ridiculous amount of internal null checks where even if something is not supposed to have nulls (like this Option structure), it will be still internally routed through dozen of null checks for half of the actions...
@ravikumarmistry
@ravikumarmistry 3 жыл бұрын
I am ok with null, it make the code less readable because not every body uses the library. I like to stick to language features as close as I can it make my code simple.
@r.c8756
@r.c8756 3 жыл бұрын
Well, that’s the downside of using that kind of functionality. This kind of decision should probably be best taken and enforced as a team and not just as a personal initiative
@AlfredoPinto
@AlfredoPinto 3 жыл бұрын
I also don't like to return nulls, but I take more like an envelope approach using this github.com/proteo5/Gali/blob/master/Gali/HL/Result.cs see the code to get the idea. You will actually communicate with the consumer method of what it happens, let me know if you want to discuss this.
@MoMadNU
@MoMadNU 3 жыл бұрын
I prefer to never return null and always provide a default value. In this case the default value is a real instance of a customer with the name "Not Found".
@eclecticx
@eclecticx 3 жыл бұрын
'Should you stop returning "null"? ' Hell no. The mere question signifies overthinking. In regards to objects, trying to avoid null, which is there for a legitimate and useful reason, usually leads to over-programming if not bad programming. Lists are another matter. Those should always be initialized and have a count of 0 if empty.
@GreenGodDiary
@GreenGodDiary 3 жыл бұрын
I agree, the code is much less readable in this case. I’m all for optional values (like std::optional) but I wouldn’t use it for nullables because a nullable already has the functionality built in, ergo the ability to check for a null reference.
@r.c8756
@r.c8756 3 жыл бұрын
I really don’t understand this disposition of mind. Questioning practices is the most elementary step of learning and improving and you never stop doing that in a career. With that mindset you can never improve... In only looks less readable because it challenges your habits.
@eclecticx
@eclecticx 3 жыл бұрын
@@r.c8756 It's good to question things and consider new approaches, but you're stepping backwards if you add unneeded complexity. Less readable is less readable; that has nothing to do with habits being challenged. A software engineer, especially a contractor, can't be successful for any considerable number of years without challenging their habits, getting outside their comfort zones, and expanding their knowledge on a consistent basis. Not returning null and engineering a work around to avoid it is none of those.
@logank.70
@logank.70 3 жыл бұрын
The thing I like about the approach, personally, is that the design tells you that you have to account for "none." Nullable reference types are good for that too.
@eclecticx
@eclecticx 3 жыл бұрын
@@logank.70 Exactly re nullable ref types, so why go to the trouble of the design? Just seems to be a case of overthinking and recreating the wheel simply because the programmer doesn't want to use nullable refs already included in the framework. Besides, nullables are something every programmer should already know how to handle, even a junior one.
@iamansinghrajpoot
@iamansinghrajpoot 10 ай бұрын
My colleague refactored my code which returns Optional to return null 😢 My heart was broken
@fat-freeoliveoil6553
@fat-freeoliveoil6553 2 жыл бұрын
I think it is a nice feature but I don't think I'll use anything like this unless it is part of .NET. I think having dependencies like this is a bit problematic. Doesn't nullable reference types basically solve the same problem anyways? You are telling the developer and the compiler that this can be null and thus should be checked (fortunately, Rider and VS also tell you this). (I get that some developers aren't comfortable with moving to a nullable project since it is a bit difficult to transition to but it is there).
@lancerhu8107
@lancerhu8107 3 жыл бұрын
Making a language more complicated to fix a easy problem.
@jeroendeclercq7580
@jeroendeclercq7580 3 жыл бұрын
The potential problem is not fixed at all. It's just another, less readable syntax to prevent it.
@nilstrieb
@nilstrieb 3 жыл бұрын
Easy problem? Null is definitly not an easy problem, there is a reason why the creator regrets it and some new languages like Rust don't have it at all.
@ScorpiaChasis
@ScorpiaChasis 3 жыл бұрын
Not sure I like this too much. I get the idea but let's say it's for newer developers. This is the kind of hack that may make their life easier but doesn't teach them good basis, it actually hides their flaws. Most 3rd party libraries still heavily rely on null. For example, the quite common newtonsoft JSON. Also if you don't learn the good practices around object manipulation and have to learn let's say JS. If you do not have the good habit of checking objects before using them, it's not going to be a fun day. In the end, I don't think this is helpful as it won't help developers improve and will just hide their lack of good practices. The value I do see in using Option is maybe proof of concept? So your demo doesn't crash? But then, what is the benefit vs a TryGet method with a nullable? It seems like a bool TryGetCustomer(Guid id, out Customer? customer) achieves a similar result?
@Yummeh
@Yummeh 3 жыл бұрын
The thing is, you can't expect someone to have good habits. Option enforces good habits. Users (new or experienced) using an API you may have witten will know the value might be null.
@Coburah
@Coburah 3 жыл бұрын
The TryGet method you propose DOES achieve a very similar result. The question is, would you prefer that over Option? If so, go ahead and use the TryGet! But according to your own logic (since the TryGet and the Option are so similar), the TryGet doesn't enforce good habits and hinders developers' improvement.
@kuroikenjin7652
@kuroikenjin7652 3 жыл бұрын
Sounds like a page out of the rust programming language.
@nickchapsas
@nickchapsas 3 жыл бұрын
Or Ada, Agda, Scala, Elm, OCaml, F#, Haskel, Swift, Nim etc
@mortenbork6249
@mortenbork6249 3 жыл бұрын
Why not use the nullobject pattern? forcing you to create a "null" workflow for the object? That is much more inline with SOLID.
@user-ro3go4fm7k
@user-ro3go4fm7k 3 жыл бұрын
I don't see the need to complicate the code with these fancy thing. In the service layer, it is still necessary to check whether the object was found. And this library will not provide any benefits. And even more, if you received NRE, then something is wrong with your code, anyway you need to fix that (with or without NRE) and you will notice it obviously. Perhaps this library will make the code a little "prettier" in the controllers, but if you haven't found the entity, you may need additional logic and "Option" construction will only disfigure your code
@feelingeverfine
@feelingeverfine 3 жыл бұрын
If you are already using LanguageExt you should use github.com/louthy/language-ext#the-awful-out-parameter
@jean-paulmalherbe8146
@jean-paulmalherbe8146 2 жыл бұрын
Great use-case.
@user-tk2jy8xr8b
@user-tk2jy8xr8b 2 жыл бұрын
The only issue with Option is it's not well-behaving: given `string F(bool b) => b ? "" : null; bool G(string s) => s == "";`, `false.ToSome().Map(F).Map(G)` must be equal to `false.ToSome().Map(v => F(G(v)))`, but it's not
@Bossti
@Bossti 3 жыл бұрын
Uses Rider, gets a like :)
@samancos
@samancos 2 жыл бұрын
Hi, what's the IDE?
@nickchapsas
@nickchapsas 2 жыл бұрын
JetBrains Rider
What is Span in C# and why you should be using it
15:15
Nick Chapsas
Рет қаралды 246 М.
КАКОЙ ВАШ ЛЮБИМЫЙ ЦВЕТ?😍 #game #shorts
00:17
Can You Draw The PERFECT Circle?
00:57
Stokes Twins
Рет қаралды 90 МЛН
1❤️
00:20
すしらーめん《りく》
Рет қаралды 29 МЛН
[Vowel]물고기는 물에서 살아야 해🐟🤣Fish have to live in the water #funny
00:53
How to Avoid Null Reference Exceptions: Optional Objects in C#
18:13
Where are types allocated in .NET and why people get it so wrong
14:35
The Right Way to Check for Null in C#
9:35
Nick Chapsas
Рет қаралды 93 М.
Manage Nulls Like a Boss and Never Fail!
21:43
Zoran Horvat
Рет қаралды 10 М.
8 await async mistakes that you SHOULD avoid in .NET
21:13
Nick Chapsas
Рет қаралды 307 М.
What are record types in C# and how they ACTUALLY work
15:36
Nick Chapsas
Рет қаралды 116 М.
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 248 М.
You are doing .NET logging wrong. Let's fix it
25:29
Nick Chapsas
Рет қаралды 168 М.
КАКОЙ ВАШ ЛЮБИМЫЙ ЦВЕТ?😍 #game #shorts
00:17