Nullable Reference Types in C# 8 • Jon Skeet • GOTO 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

This is a talk from GOTO Copenhagen 2019 by Jon Skeet, +34,000 answers on Stack Overflow. Give the full talk abstract a read below:

The biggest feature of C# 8.0 is undoubtedly nullable reference types. Rather than trying to rush through all the new features, in this talk I'll just talk about this one. What's the point? What's the syntax? What's should you expect? What might be unexpected? I'll go into all of this and more!

What will the audience learn from this talk?

  • How C# 8 allows developers to express nullability in the type system
  • The benefits of nullable reference types compared with earlier versions of C#
  • Tricky areas and "gotchas"

Does it feature code examples and/or live coding?
The talk will be live coding for the whole time, with samples on GitHub

👍︎︎ 17 👤︎︎ u/goto-con 📅︎︎ Mar 06 2020 🗫︎ replies

[removed]

👍︎︎ 56 👤︎︎ u/[deleted] 📅︎︎ Mar 06 2020 🗫︎ replies

Can't find good words to comment this video. I have not known how Jon Skeet looks. I know his SO achievements, I've considered him a legend and a hero. Now I saw him and I'm... confused

👍︎︎ 6 👤︎︎ u/sasik520 📅︎︎ Mar 06 2020 🗫︎ replies

"We must do better"

Yes, Sir! I will force my daughter into coding and my son into any other job, no matter what!

That said, the talk itself was very informative, thanks.

👍︎︎ 6 👤︎︎ u/StrangerDangerBeware 📅︎︎ Mar 06 2020 🗫︎ replies

This is awesome I tryed using these a month ago but I couldnt figure out why I was getting so many errors and the project I had in mind was written in C#7 with .net framework so I just went back to what I had to begin with.

👍︎︎ 1 👤︎︎ u/LordVirus1337 📅︎︎ Mar 06 2020 🗫︎ replies
Captions
[Music] good morning I will start in the way that I have started I think every conference a newsgroup talk I have given for the last couple of years which is to say that this room is not diverse enough so you're not alone in this but apparently I need to go to China if you give a talk at Alibaba and hopefully 50% of the attendees would be women I was giving a talk at a user group in London recently where the diversity was 50/50 but that was 50% of the room had beards and the other 50 didn't we can do better and we must do better I will end my rent at that point so see shop 8 I have been giving see shop 8 talks for it feels like now a very very long time and the whole of c-sharp 8 is far far too big to give in one talk or in 150 minutes lot so I've broken this up so today we're just talking about nullable reference sites now for most of the time that I've been talking about c-sharp 8 it hasn't been out but it now is if you've got Visual Studio 2019 and you've kept it up to date then you have nullable reference types out of interest how many people have already played around with them a bit okay I'm sort of glad that it isn't all of you because otherwise you might not need this talk at all and yeah if any of you suddenly decide actually I know all of this then feel free to to leave that's fine if you have questions unlike most of the talks here I'm not going to wait to take questions at the end please just ask them in the app I can see we've already got a couple about Stack Overflow on there if you could keep it to c-sharp eights and Noble reference types that would be great but yeah please do ask and if if I haven't noticed that you've asked because I need to look over there just shout look at the questions and I will do so because there's nothing worse than waiting 10 minutes until the code that is relevant to your question is off the screen before I actually notice so nullable reference types in c-sharp 8 you may think that the title of the talk is odd big cars C sharp has had nullable reference types since day 1 all reference types are nullable and c-sharp 8 sort of half changes that but brings them back again it will become slightly clearer why the feature is called nullable reference types rather than non nullable reference types as we go along but I do want to give a little bit of background as to the purpose and I'll draw a an analogy with generics so back in c-sharp 1 if you wanted a collection of things you might use ArrayList and you couldn't say what it was an ArrayList of and your code worked fine but once you started trying to access the values in the list then you would have to cast them so if you documented right this is an ArrayList of strings and then everyone would have to cast and there be no protection against someone adding something else and the interesting thing is during that period before generics I very rarely got an invalid cast exception because I was trying to do the wrong thing with elements of the list or someone had added the wrong thing so adding generics did not improve the actual bug freeness of my code but it did allow my code to be much much more expressive so I could be more confident than there weren't bugs nullable reference types are very similar there are significant differences as well but if you hear people talking about nullable reference type says great this means we'll have no more null reference exceptions that's kind of true but not the point in particular if you don't get null reference exceptions now you shouldn't think that means I don't need nullable reference types ok it's primarily about allowing your code to express more in the type system it's probably best if we dive into some code at this point and I once I've given the most basic of demos I will give a few takeaways that I'll probably repeat several times so that if you leave with nothing else you'll get those few so let's start off with a simple person type and this is just it's immutable it's not sealed I could seal it it takes first name last name of a middle name in a constructor and copies them this is using c-sharp seven tupple literal on the right-hand side and deconstruction to the properties on the left-hand side really handy if you're if you're not familiar with that syntax become familiar another way as I sort of highlighted earlier on all of this code is available on github look under the C sharp 8 bit of it so we have a person constructor that accepts the first last and middle name and just copies them into properties I should note if you're ever trying to model names don't do this because it's very if I say culturally insensitive that sounds a bit kind of snow flaky it really doesn't model the way that people have names in the world but it's really useful for the demo so we're going to construct two person objects myself with a middle name of Leslie ma Miguel de Icaza who does not have a middle name so we're passing in null okay these lines of code both work this is currently think c-sharp seven which this effectively is in terms of nullable reference types because although I have enabled nullable reference types in the project file as we can see here this nullable enable I've disabled it again at the top so this is not using the level reference types yet so so far so good we construct the person we've got a null middle name for Miguel and then we call this print name length method and there's nothing special about this I'm not using interpolated string literals not because they won't work it's just it makes it easier to highlight bits of things and change just just some aspects of it likewise I could just do person dot first name dot length person dot last name dot length but again all the purposes of teaching for the moment I've separated it out so there's no reason other than the teaching aspect so what's going to happen when I run this the it will print first equals John last equals skeet middle equals Lesley and then it will try to do this film a gal de Caza and it will go bang because of middle dot length and let's just prove that and sort of show how we're going to run this and there's a little app chooser that I've got hopefully white-on-black is still okay so if we run basic demo we get a null reference exception just looking at the questions I won't talk about default implementation for interfaces in c-sharp eight in terms of c-sharp community and failed to use good design to solve the null problem you can't because before c-sharp eight you couldn't express that something couldn't be no even if you designed code so that nothing ever was now that wasn't available in the type system so that's a a good relevant question because it's showing that the communicate community can't do anything about a reference can be null if you create an array that will be full of null references and we needed more power in the type system itself right so we've got broken code right now it throws a null reference exception we're going to turn on nullable reference types and suddenly we will get a warning it does actually come up as a warning cannot convert null literal to nan na level reference type now that's a fairly wordy way of saying you're using Dahlan you shouldn't be and it's it's because by just disabling that removing that has none of all disabled has changed the meaning of all of this code and that should be slightly alarming to you previous versions of c-sharp have always tried to be very backward compatible you know where everything works the same way as it did before it's all fine and here we're saying if you turn this feature on the meaning of all of your code changes that is alarming but it's a good thing really I hope that part of the point of this talk is to persuade you that it is a good thing you may not feel it's a good thing when you turn it on because not only will the meaning of your code change but the compiler will shout at you a lot with many many many warnings this is entirely to be expected I really got one here because I've designed this demo around all of this when you turn it on in your code how many errors how many warnings you get will probably depend on what you've got the limit or number of reported warnings and the size of your code base we'll talk more about migration later on ok so we've got a problem and one really important takeaway is the compiler is not saying ok here's how to solve this you can't tell the tell Rozlyn please fix all of my code so it's null safe again and get rid of all of those warnings and it could do that but it would have to make choices for you and it could make choices to make everything nullable and it would be equivalent to your C sharp 7 code and you'd hate it because it wouldn't be giving you anything there are options here there are two choices we could decide that we're bored and want to go straight out for coffee and we'll just say well we don't want that to be no fine I'll use an empty string instead at which point no warnings job done off we get coffee and more interesting is to say you know what sometimes I want things to be nullable so if we say I want middle name to be nullable we need to make the parameter in the constructor nullable which we do in the obvious way if you've done any c-sharp and used nullable value types you would immediately reach for a question mark here it's worth noting that it's not nullable string ok that that's still trying to construct a nullable value type but strings a reference type I'll come back to the differences when we talk about Derrick's so um note that now now that the parameter is nullable the warning has gone away from our passing a null argument yay we've got another warning instead we now when we're trying to copy from the nullable parameter to the non nullable property we we're told hey yo you're doing something that may be wrong there okay so let's make the property nullable bomb and now we've got two warnings now what i find interesting is you laughed then and every audience I've ever done this with laughs but this is the experience you should absolutely expect okay not only do you get a load of warnings when you start but you fix things up and you will have more warnings in different places it's like playing whack-a-mole with warnings and the reason for that is that you are propagating more information through the system and the other bits of you've got the code over here that you've suddenly said this is nullable this bit of code is reacting to that bit of code and it's changing its mind about how it feels about that knowing that that might be null and I thought it wasn't going to be null and this is where we finally got to the cause of our null reference exception earlier is when we were doing middle dot length where middle was null and now the compiler knows that middle might be null so it's saying hey this is a bad idea so this warning whack Amole is a good thing but you need to be prepared for it and understand it and don't just get dispirited so there are two warnings here and they're kind of interesting so the first is that we're trying to assign from person dot middle name which is nullable to a non nullable local variable okay we would expect that to have a warning because we've already seen warnings like that but what about this warning for middle dot length that's a little weird because we've said here that middle is non nullable okay it shouldn't be no and the compiler is warning us anyway because it might mean oh and it's now time for big takeaways the aisle that is generated other than adding some annotations on methods and properties and things to say hey this might be now lul this might not be Knoll the aisle that's executed does not change at all when you do nullable reference types it's really really important to understand that it is not changing the behavior of your code if you turn noble reference types on and ignore the warnings so you don't change your code at all and if you dumped that with a old azzam before and after the only difference you would see is in attributes your code would still run and if it had bugs before it will still have bugs if it didn't have bugs then even with all of those warnings it still won't have bugs and the sort of corollary of that is that nullable reference types are really a compile-time thing they leave some metadata lying around in attributes but there's no representation in the CLR the CLR has not changed at all which means the type safety is also only compile-time if you persuade the compiler or ignore the warnings then unlike with our ArrayList example earlier on if I try to cast something to string because I thought well this is an ArrayList of strings and someone have put something that isn't a string in there it would have gone bang the compiler sorry the CLR would have been checking things for me that is not present with nullable reference types the value of a nan nullable local variable can absolutely be null and in fact you can sometimes get it without any warnings I mentioned arrays earlier on and string array equals new string 10 I'm not entirely confident that this will not worn but yeah no warnings that will go bang the behavior has not changed okay I am gonna keep saying this I'm afraid the behavior has not changed so array zero is null the compiler isn't warning you in this particular case because it's kind of hard to reason about strings it's very easy this time because we can see we just created it of course everything's going to be null but what if this was string array equals get array four in some method we'd have no idea whether it was null or not so we the compiler trusts us in this particular case here we can say it's it's an array of nullable strings and at that point it says whoa that might be no don't dereference it okay so it's not bulletproof it's not enforced at execution time it doesn't change your oil it may sound like I'm really trying to sell this down and say it's a useless feature it's really really not being able to know when things might or might not be null even when it's only to 90% confidence it's still a lot better than 0% confidence or just relying on documentation which we all know gets out today easily so back to this middle dot length the compiler isn't trusting that just because we've put something into a variable middle it it's definitely not null because it's given us a warning here but we could have turned that warning off or we're clearly not doing anything with the warning at this point so we need to do something else to get rid of this warning let's make that a nullable local variable that's an easy warning to get rid of and let's just use the null conditional operator so middle question mark dot length so that that expression is narrow of type nullable int and this code will now work in the it won't go bang and we end up with middle equals blank now I am useless at user interfaces but I still think that's bad here I can spot that that's not an ideal user interface let's see if we can fix that to not bother printing middle equals at all if we if middle is non null so there are we could say if let's do something if the middle name is null else do the the full thing or we could use if it's not null and these days the sort of blessed way by the c-sharp team of determining whether a reference is not or not if it's if you want to match against null is null to say not null is object okay yes you can use equals equals null and not equal to null they don't actually do the same thing as is null is null is a really efficient way of doing it says is this reference null anyone care to think what the difference is with that overloaded operators yes exactly that's cheating you've heard Madson talk about this so yep that's calling an overloaded operator for no good reason we we're fairly confident that the string overload is doing the right thing but why invoke more code than we need let's just use is null so if it's null we'll print out just the first and last names get rid of that okay now here's the magic bit observe the lack of warning now I'm just going to get rid of the the list of warnings here so you can see more of this at a time that's enough okay so middle is a nullable reference type it can be null so you would expect the compiler to say you're not allowed to do that because it might be null but the compilers smart enough to say hey it's okay we've just checked whether it's null and the only way we can get into the else block is if it's not null so this validation this checking is not just based on the type of the variable it's a little bit like the compiler keeping track of definite assignment and saying you can't read a variable unless every possible execution path says it's already been assigned it's like that but with null ability and it doesn't matter what the type of the variable is it will still keep track of I think that might be null or I don't think that will be null and will warn you appropriately so that's fine we've got something similar in terms of definite assignment for local variables now let me scare you a little more let's get rid of it let's say we don't like these local variables will say if person dot middle name is null will write person dot first name dot length person dot last name dot length no problem so far and still no warnings and the first time I saw that it terrified me because this is definitely definitely not safe code we were reasonably confident if the middle local variable wasn't null when we checked it it's not gonna be no later on but these are properties we're talking about now these are this is executing some code here and it's executing the same code again who knows whether it'll get the same answer it might have an implementation like this so this is a similar a smaller example of the same kind of code and again it compiles without any warnings and this is a really bad idea this is not safe this could I'm not going to run it thousands and thousands of times but this could absolutely throw null reference exception because if you call it first just before the start of a minute and then by the time it reaches this bit of code and let's face it these will be nanoseconds apart in terms of execution but the second time it calls the name property it could then the clock ticks over to the start of a minute it returns null bang null reference exception this was bad code before c-sharp ate it's still bad code in c-sharp ate and the compiler isn't warning you about it okay it doesn't try to be bulletproof now you know no one's actually got code quite this bad I hope in their production systems but there are other ways that properties can change if you are doing things if you are mutating an object in one thread and doing other stuff in another thread then you could easily have this kind of situation don't do that it's a really bad idea to do unguarded mutation across multiple threads let me do a few more things with this code base first to show you the the second bit of new syntax so I've shown you one bit of new syntax so far which is adding question mark to a type name actually I'll I there's a couple more bits within generics as well but note that I've got a to do here validate arguments let's do that now so I'm going to at this point go into a block body because otherwise it ends up looking a little awkward and I'm going to do first name equals and then I've got another another class elsewhere in this called precondition where they check not null and normally so I've had several classes like this over time normally I have a second parameter that's the name of the parameter as it were and I would normally write name or first name and it gets a little bit annoying but it's really useful for diagnostic purposes I've kept it simple just for this talk say precondition check not null last name and then we don't need to do any checks for middle name because it's noble okay that's fine that is I've changed the code what should I have done before changing the code I should have written a test how would I test that this code now behaves where I wanted it to before I haven't got any nougat package any tests installed right now but let's just because every time I do this talk I think why didn't I install any unit did it to do that we'll take a little bit so let's do I'll just do the class at the bottom so it doesn't get in the way of other demos but in the same file right so public class and person test fact nope test I'm not X unit sorry I use different tests environments depending on whether I'm doing things personally or not so we'll say first and they constructor first name must not be no however you want to name your tests that's fine by me and it's now got that so we're going to do assert throws and argument null exception and then what are we going to do here we need a new person null last middle newline and the trouble is that gives us a warning and I don't want warnings even in my test code so I'm going to use what Microsoft what the man wants you to call the null forgiving operator and what I want you to call the damnit operator it's basically saying no I want this to be null damn it so we use an exclamation mark so can I trust all of you we'll call it the damnit operator every time you need to refer to it yes yes thank you what compiler am I using am I using the Microsoft compiler framework no I'm using Rosling that's what the communities always called it and what's work what we're going to keep calling it we will keep calling this the damnit operator so the damnit operator just tells the compiler whatever you thought about the null ability of this expression and it doesn't have to be a null literal I could have done you know string this is null equals null you know it can be any expression and it just says whatever you thought pretend it's not null it's you this is not the null you're looking for and I want to know what's the key takeaway that I asked you to remember before as well as the damn it but from earlier on it doesn't change the meaning of your code even though damnit operator does not change the meaning of your code it's a little bit like a cast in that you're telling the I know better than you trust me on this but it's saying no really really trust me you don't even need to check because it would be awful if the compiler inserted a check in here to say you know if it's null I'm gonna go bang early because we like exceptions happening early no we really really want to pass null into this code so that we can check that it throws argument null exception and this is I'm gonna heart back again because this all links back to it doesn't change the meaning of your at the behavior of your code you need to check for this not being null because if you don't some code could pass null in and you had end up with a person object that was violating its own contract and you don't want to do that don't be that developer you know it's much better to find them find the problem early on and throw an exception then you've passed the person through multiple levels of all kinds of stuff maybe serialize it to JSON deserialized it on an entirely different system and then you find out it's null no you really want to say sure this isn't meant to be now I will make sure it's not null ways that it could be no r1 someone ignores warnings to they disable warnings because hey it's only a warning three they haven't enabled nullable reference types at all or four they may not be able to enable nullable reference types you can still call in to c-sharp eight code from c-sharp 7 code because i can create a new get package with this with this person class in and I don't care what version of the language someone's using when they try to use it now that is all kind of annoying to do having this precondition everywhere so it is possible that in a future version of c-sharp I'm kind of hoping c-sharp 8.1 that we'll be able to add some syntax to the parameter itself and the the thing that has been proposed by the team is adding an exclamation mark there and note that it's on the name of the parameter not on the type you might expect and frankly so would I that you would put it there sort of this isn't just not null it's not null and checked to be not null and I would quite like that to be honest but the the team has at least been arguing that no it makes more sense because it's not about the type of the parameter but what we do with the parameter inside and something and if this becomes a thing then we could get rid of the precondition check not null because the compiler would be adding code that effectively does that for us and that would be a lovely lovely thing okay I believe that's all the basics and I've now just remembered I haven't looked at these for ages so quickly how does one code like a girl by doing it well off topic copy/paste that's horrible didn't see a witch copy/paste come why don't we just avoid doing mutation yeah sure I prefer using immutable types where possible a it's not always possible and be the c-sharp programming language is not in the business of dictating how you code someone's asked about house value which is fantastic because it lets me come back to a difference between noble value types and nullable reference types nullable value types have an entirely different representation in the CLR they are a whole different type nullable of T where T is the non nullable value type so nullable event and int look entirely different to the CLR so you can do if food has value and that uses the has value property from the nullable value type I can't do I'm assuming that this question came in when I was writing if person got middle name is null or earlier on I can't do middle name that has null because there isn't such property it would have to be a property in person itself sorry in string and it would go bang if but if middle name is null because there's no separate type here the the the opposite of that is I don't need to do person dot middle name dot value dot length because I'm not trying to get at the underlying not null value there is no nullable string it's just string as far as the IL is concerned as far as the CLR is concerned and I do apologize to my sign language interpreter here for all the acronyms going around I hope it's not too too difficult for people watching is there a shorthand for throw if not null no there isn't there might be four parameters in c-sharp 8.1 but I think that there's still room for being able to do things in imagine you could do middle is person dot middle name and well I'd imagine that that would inject something saying whoa just check that it's not null as I go but I don't think there's anything even planned for that right I'm now going to move away from the questions and come back to my script as it were and so we've got a few things a person is exposing some properties two of which and non nullable one of which is knowable you can do the same for method parameters those can be nullable or not nullable you can do the same for return types i would ask you what do you think the the signature for string dot is null or empty should look like so if we had you know class string utils public static well what are we going to put let's put bull is null or empty string text okay we need that to be nullable because there's no point in saying is this null or empty by the way it can't be null that would be foolish that would have warnings all over the place and in fact ironically in no time at the moment i've got a bunch of null forgiving operators damnit operators where i call string dot is null or empty with something that i know might be precisely because I know it will handle it and the version of the framework that I'm targeting doesn't have the annotations to say the right things so it wants it to be not nullable and it might be no so yeah that's just cool string dot is null or empty for the moment and that that is absolutely correct but it is not giving us all the information we want so the type system is not rich enough to convey the meaning of the method and when it comes to null ability that's really really useful now I have a slightly bigger version of this with some calling code that shows you why so it's not it's conditional return right so I've got my own version of string string dot is null or empty so that I can show you in a minute how it how the magic actually happens but suppose we have this so we've got something that you imagine we're getting this from somewhere else it might or might not be null if it's null or empty we're just gonna print is null or empty otherwise we'll print text length no warning and I haven't disabled warnings or anything there's magic going on the compiler has to know that if string dot is null or empty returned false that means the argument text in this case was not null it can't get that from the signature itself that's just not part of you know it's it's not gonna magically say oh it starts with is null therefore I'll work it out from that I've heard strange of things so what actually happens in in early versions of the c-sharp ate compiler the compiler had hard-coded I know what C sure what string dot is another empty means and it did the right thing at one point the c-sharp team were going to introduce a sort of little meta language that you could put in an attribute above the method to say the relation between inputs and outputs and what it what it would all mean but I believe they I suspect what happened is they started doing that and then found that they all boiled down to a relatively small number of cases so instead of one general-purpose attribute with a whole extra language inside which would have been a nightmare to design and then specify instead we have some very specific attributes so string dot is null or empty its first attribute which is of type nullable string has this not null when false so this means when the output of the method the return value of the method is false then the attributed parameter text was not null and that's how it knows that's how the compiler knows to feed that into its idea of whether the variable was null or not let's look at a slightly odd or example of dictionary try get value so dictionary T key T value T key and T value can be any types you like including non nullable reference types so we could have a dictionary ball string okay and we know about the try gate value method that was designed a long time before nullable reference types came along try gate value will return false if the key is not in the dictionary and the out parameter out string value here out T value value in the real site will have the default value for the value type for T value this isn't value types as indelible value types etc I apologize for the overloading of the terminology so that leads to the question so what's the default value of non nullable string what do you think the default value is now it's a real problem it's very odd that default of T is not really a T or violates its own contract but the compiler needs to no in order to make things safe it needs to know that if tri-gate value returned false then even if I've got an on nullable out parameter it might be null after all in fact it definitely will be but this is saying may be null when false so it's saying again when this returns false the out parameter will be null and therefore the the compiler warns us if we try to use it come on yes there are a bunch more attributes I will show you one more so this is quite related to link to XML where there are a bunch of operations in link to XML particularly with operators where say X element you can cast the next element to string and that will return null if you actually passed in to the conversion a null x element so not an element that's got no text value but you passed in a null reference it doesn't go bang it just returns you know this sort of null propagation is really useful and here's a sort of trivial example for it so if we pass in null to the method it will return null if we pass in something non null it will return the same string twice and that's clearly going to be not null so non input leads to null output not null input leads to not null output the signature has to be this because we definitely want to be able to accept null and the output well it kind of depends on the input but there's no way we're specifying that in the signature itself so we have this slightly bizarre not null if not null so it's saying the return is not null if the specified thing input is not null as an aside it's kind of annoying that we can't do name of input but input is not in scope in the attribute declaration okay there are other attributes that are interesting and if I had lots of time I would go into them but I won't because we don't have time I will talk a little bit about generics and about how they are a nightmare and you get certain aspects of language design that sort of butt up against each other and generics and nullable reference types clash in a fairly unpleasant kind of way there are other things that do this dynamic typing and explicit interface implementation are likewise not friends I will very quickly do questions first so the CLR could have changed instead the question is could the CLR and language have changed instead so that things could have been done in the same kind of type safety way that we have for other things and it certainly could have been done but a I think it would probably be now I don't know about efficiency they could probably make it efficient I suspect it would mean that adopting c-sharp eight would become much more of a big deal much much harder basically we've been going for 20 years it's too late to change something quite that radically if this had been back in 2005 yeah maybe but there's a lot of code that this way of allowing you to migrate and fix the warnings and maybe disable the warnings if you want for the moment and you know that you haven't made your code any worse so you can do things a bit at a time it's far more pragmatic this whole feature reeks of being pragmatic as opposed to dogmatic so it's trying to get let's make the world better for loads of people rather than giving something that no one can use but anyone who does use it has a perfect experience let's maximize the value yeah that should just be his null thank you for that today I went talk would I recommend making the warnings for knowable reference types appear as errors that's a good question in terms of migration I would say do that after you've done the migration when you've got it down to zero warnings then make it an error that makes the migration easier when you've got multiple projects referring to each other you don't want stop one project from building entirely before you can sort of see the impact of things but yes warning says errors is generally a good thing and I would encourage that you know regardless of whether you're using the little reference types it does mean that things that API designers may viewers not breaking changes like making a property obsolete will give you a warning if you've got warnings as errors turned on you'll get an error but you've kind of opted into that you've said I'm willing to address that problem as it comes up and that's I think a responsible attitude to take but you know there needs to be a bit of give-and-take with API producers right onto generics so there are this is one other little bit of new syntax we can have a not null constraint and it's not quite as useful as you you might want it to be so it basically says T here has to be a not null non null abour value type or a non nullable reference type which you would expect to then be able to say you know that's fine I can now have a property of the nullable version because there definitely will be a null available version for any T but it will be different depending on whether T is an honorable value type on a non nullable reference type so if the compiler had to try to get that to compile there is no il that could actually represent it because nullable value types were added in as part of generics with a separate type and knowable reference types really weren't added into the CLR at all so I'm sure that is a useful constraint in some situations but it doesn't do what you might to be able to do if you have I'm gonna move this up as a more familiar one so not nullable of t not nullable r ft just has our old friend where t : class so by default any time that you've got hey this has to be a reference type in nullable reference enabled code that means it has to be a non nullable reference type so I've got some examples of invalid code later on so you can create not nullable ref of string question mark that's only a warning but the idea is obviously you're getting rid of all the warnings if you want something and you won't say it's explicitly it might be a nullable reference type you put class question mark and one interesting difference is you can put if you know that T is an honourable reference type you can then accept the nullable form of it so you could have a a null ignoring list of T where T is class and then having a maybe add method that accepts a t question mark because maybe you've got a lot of callers that have that and don't want to have to check themselves all the time and that could say well if it's null I'll ignore it otherwise I'll add its - okay you can't do that I believe this is where I find out that it actually works anyway right that's an error whew because if you've got nullable of string as T sorry Oh string question mark as T then string question mark question mark you know it really really might I'm not feeling good about this it might be null it probably is no no you can't do multiple strings okay string now there's nothing like that so you can't do maybe nullable ref of string question mark and then have a string question mark question mark so that's generic constraints there are oddities as soon as you start using generics you will you'll want to think about these constraints because you'll have things like default of t and you need to be aware that that might not be a t because if it's non nullable you get null finally i have one minute and i will just mention the other options i've shown that we can enable or disable novel originally these were just true and false but there are other options as well you can have annotations I believe that's valid and warnings and that's because null ability has effectively been and implemented as two different aspects one is am I allowed to use the new sink tax the the damnit operator and the question marks and stuff and that's called the annotation side and you can have that on kind of alarmingly without the warnings part so here is annotated code that is going to go bang no warnings nothing and I've explicitly said disable warnings enable annotations so all of this you can do on just a region or in the the overall project file and you can have the opposite thing where you're not allowed to say that it might be null but you can still do it you can still get warnings I'd expected to get warnings oh yes if I put if I copy this line of code here then yes we get a warning saying whoa you're dereferencing something that might be null and I think we'd still get it up here as well because we haven't checked yet that it isn't null nope I near ate this code yesterday I haven't been experimenting with it as much but this this annotations the warnings only without annotations or annotations only without warnings are a little odd situations so I'm 35 seconds over time already thank you for all the questions that I couldn't get so I'm really sorry about that I will hang around here as long as I don't get booted out so come and talk to me in person so things to take away this is primarily so that your code can express itself better the il that is generated by turning on nullable reference types doesn't change the behavior of your code it just changes what's attributed expect loads of warnings and go through and fix them as an iterative process and we can and must do better on diversity thank you very much [Applause]
Info
Channel: GOTO Conferences
Views: 10,475
Rating: 3.9795918 out of 5
Keywords: GOTO, GOTOcon, GOTO Conference, GOTO (Software Conference), Videos for Developers, Computer Science, Programming, GOTOcph, GOTO Copenhagen, Jon Skeet, C#, C Sharp, C# 8, C Sharp 8, Nullable Reference Types, DotNet, .Net
Id: 1tpyAQZFlZY
Channel Id: undefined
Length: 50min 40sec (3040 seconds)
Published: Fri Mar 06 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.