What's New in C# 11 | .NET Conf 2022

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
>> [MUSIC] >> What we've done is we've added a bunch of new features. >> Absolutely amazing. >>.Net is a general-purpose framework for building all of these types of applications. >> You can be productive and code and build your UI quickly. >> What? >> The home screen shows you to sauna temperature. >> You can see down here on the lower right, it now knows the garage door is open. >> Let's jump to the code now. >> The.Net community is just always been a great community to be a part of. >> This really is a state of the art technology. >> You can actually download this right now. >> And get right to the code. >> Built some new applications on.Net core. >> Please have a great conference. Ask us lots of questions on Twitter, we're going to be there all week. >> Welcome to. NET Conf, Day 2, this is 2022. Dustin, I can't believe we're here in the studios together again at. NET Conf. >> It's exciting. >> It's very exciting. Welcome everyone out there. We're ready for another day of.Net. All the new things coming out, lots and lots of talks. Today let's start with C Sharp. My name is Mads Torgersen and I'm the Lead Designer of C Sharp, I lead this merry band of designers of which you're one. >> I am, my name's Dustin Campbell. I'm an architect in.Net tooling, but I am also on the C# design team and which is really fun. >> Yes and it wouldn't be the same without you. Today we figured we just skip the slides and go straight into code. If you look at our screen here, we have Visual Studio already showing us the first warnings in our code today. We're going to try to make them go away like a magic trick. Excellent. >> First up we want, it's tradition that Mads and I in our demo we start with a very, simple person demo where you have a person class. Now, what's cool about this is that we were using some of the new features that we've introduced over previous releases, we're using a nullable string or there with a question mark using a knit only properties. But there's a downside to this as well. >> We really want to make it nice to use object initializers and not have to do constructors for everything that can be a little cumbersome. But something is a little off, which is that with object initializers up until now it's always up to whoever's creating the object to decide which things to initialize and which not to initialize. That leads through here, because you see there are some squiggles there. >> There's some squiggles here. This is where the blessing of nullable is helping you. Essentially it's telling us that, hey, we haven't declared these as nullable, but there is an implicit constructor that will get called before the object initializer up here. It is run before those properties get assigned. Technically, these properties will hold a value of null and we have said we don't allow that, and this is a stumbling block in some use cases where I want to use object initializers. Often we've tried to find ways to work around this, and so users often are doing things that feel unnatural. You might have to assign it to null just to tell the compiler. >> It is. But this now you just move that. >> You say no bang. >> Now we have a place to put a bang and say and I know what I'm doing. >> Try and pass code review with that, this is thing we have to do and it really is uncomfortable. >> You might even try to get around it by assigning a non nullable string type you. I'm just doing something. But you're really just hiding it problem that's still there, which is that the object is not properly initialized and you get the compiler to shut up about it. But it would really be nicer if you could ensure that it was probably initialized. >> There's another issue here too, which is that the object initializer itself doesn't initialize all the properties I wanted to. Like with a constructor, I can be very prescriptive about what things need to be passed, what I'm expecting from the user to initialize the object in here. Even if I assign these to null or I sign these empty string, I don't really want those. But if somebody's using an object initializer, I can't guarantee that they've actually filled in the last name. >> Wouldn't it be nice if you could tell the person creating the object, actually you have to initialize, it's a required. >> We can do that now. The nullability warning goes away because we're expressing in the language that this is a required property therefore, it means that when it's initialized, it is going to be initialized, we don't have to worry about some of these details around this time where it might be null, we've guaranteed that. If I do the same thing with last name, then we'll leave it there because I haven't specified last name up here. It says required member must be set in the object initializer or attribute constructor. Now that's curious, attribute constructor. >> Let's celebrate the Red Square. You're now expressing a contract. Whose job is it to initialize this property, and unless you put required its a classes own responsibility. But if you could require it, you're pushing that responsibility, that requirement onto the person initializing the object. >> We can correctly initialize it as that contract define. Now, that attribute piece that I mentioned earlier was goofy where it said to attribute constructor, and it turns out since C# 10, we've allowed properties to be assigned as optional parts of the initialization of an attribute. While doing this felt like we should also attack that problem as well, since the object initializers are all about initializing an object through properties, attributes also have a way to do that. It's merged together. If I were to make this an attribute, you'd see the same error. We could just call it an attribute. Sure that's a thing. If I have the same code here, you'll get the same error. Now with an attribute, you can also do this, it's a nice way of just taking it all the way through the language, but also back to C Sharp 10 and improving the experience that already existed there. >> But now you can actually have the old style of optional attribute parameters also be required. >> Yeah. It's fantastic. Let's move on. This has been a cool feature. I'm really excited about this because it feels like over the course of the language, we are continuing to make these small improvements across initialization and really getting to a place where it starts to really coalesce and feel really good. >> It's been a theme for a couple of releases now, to make an object initialization, flow more naturally have more expressiveness and more conciseness. It's another step in that direction. >> Well, let's take a look at something else. C# 11 is full of features. Since we're looking at things that, hey, improved C# 10 from long ago there was another sort of things that we've wanted to do over the years for many years, that also appear in this language. >> Everyone who's had the pleasure of doing math and C# and trying to abstract over is a specific number that you're talking about, even if you just used system.math, you've gone and seen all these overloads, that's an overload for each possible numeric type of absolute value and so on. You might wonder what does the code look like inside of all of those overloads. It looks exactly the same. But we've had to write it like 12 times however many overload [inaudible]. >> Just to illustrate this the demo we have here, there's a function, again we're using top-level code here, but there's a function inside that. We have a method that will take an array of integers and just adds them up. >> It's a new beautiful numeric at how good. >> It is genius, we slaved over this one day we really weren't toiled over it, and then we're passing it array in here. If I run this, you can see that it adds them up successfully, which is great. But now if I wanted to make this work over other numeric types, what if I wanted the different bytes or doubles or anything? >> Basically I have to copy this, copy and paste this and do it again. >> What really would want is to make it generic. We want to say add all of T and then this T, then somehow, you know. >> We're going to return a T, and now we're going to take a T array. I guess this is going to be a T and that'll do it. >> That would be cool if you could do that. Of course, you can't plus random T's and they can't be zero. But if this was just all about instance members, we would put a constraint on engineering. We just say where T something, something. Wouldn't it be cool if we could put a constraint on that is like, somehow says that I'm a number? I have operators and things that make me a number. >> Yes. I did that and I used INumber which is new in.Net 7. When I hover over that, I've seen that now that the plus equals error went away. In fact, there is some interface that has the operator plus that is generic and can be used. >> It's just magic. >> It is magical. The only problem I have now is I still can't convert int to T. But you know, I know that when I'm doing generic methods, I can dot in and look for the static things. >> Well, you didn't use to be able to on a type parameter. >> That's correct. >> But now, there's stuff in here. >> There's one that would work if I were a mathematician and really good at math. I would know that additive identity is what I need here. For the rest of us, we can just say zero. Now, this is completely generic and if I build and run, still works. >> The sum of those numbers is still 15. But now. >> But now and wait, there's more. >> What if you use another kind of number? >> Yeah. Right now this is an int of int array. But if I throw a double in there, that will cause the inference of the array tie to double. Now it's calling add all with an array of doubles. It still works. >> Now it's using doubles plus and zero. >> This is a generic math in C# 11 and it is driven by really a much larger feature. >> This is the domain that we chose to double down on for. >> I see what you did there. >> We're not just inting down anymore. We're doubling down on the thing that where we took the PCL put interfaces and everything int. But it's really a special case of a broader language feature that we added. That is allowing static members and interfaces to be virtual or abstract. >> I will go to definition on this INumber type and we'll see that and see what this has. This has static members. These are actually, interestingly, if you get to how this is implemented, they're just static members. They are default interface members as well. They have default implementations. But this INumber brings in a whole ton of interfaces because there's all sorts of things including that I addition operators that we looked at before, if I were to have 12. Now you see that, well, this has a static abstract operator. >> Yes. >> A plus. >> Operators are really just static members. They're one kind of static members and all the different kinds of static members can now be abstracted over an interface. You can say whoever implements this, they must have this operator, they must have this static member, like we saw those static property zero before. Then you use generics to get at those, like we saw in our example there. >> It's a great feature for the generic math domain, which is really what drove us to really do it. >> But before you move away from here. >> Sorry. I didn't know. >> You didn't know it. >> That's okay. >> I also wanted to call out another little language feature that we added just as we here, which is that you can now overload your operators. That all the ones that in their primitive form haven't checked form can also overload, the plus operator with a checked overload, and in that case, that's the one that gets picked if you're in a check context. >> This was again, it was something that came out of us trying to implement this generic math domain. This is needed to really fill it all out. You can see that we went a little nuts with filling it all out. If I look at the INumber again there's just a lot of interfaces here and you can see the scroll bar. It really is composed of many interfaces that can be used to define your own numeric types or things that can be constrained on. But there's also something I want to call out this, really interesting because it has nothing to do with numbers at all. But it's just a really great use of this new feature that is static abstract members on interfaces or being able to implement static members from interfaces, in a sense because you can also have the defaults. >> Let's have a look at that. Being parsable, what does that actually mean? >> It means to take a string and give me back an object. >> An instance of the type. >> Yeah. >> A type that's parsable, that doesn't really mean that things of that type have an instance member on them. If you walk up to like a person and say, parse yourself. Well, too late, it's already a person object. What you really want to do when you're parsing something is you want to get a string and then create the person. >> Yeah. >> That's usually the job for a static member, right? >> Yeah. This goes really well on the PCL, because we have these try parse methods on our numeric types, but also on things like do it. Which I am not adding together, but they're also still parsable and now you could constrain on this interface to be able to have a little factory method that might, given a string produce things out of it. >> Yes. >> This is really, if we can have a look at that, there is a parsing to try pass that parses a simpler one of them. It's a static method. It's abstract in the interface. Or you're telling people who implement the interface they want to be parsable. Well, you got to have a static parse method. You take in a string and a format provider and you return the type of yourself like Susie, the intention is class C when it implements the I parsable into flight, it will pass itself as the type argument so that the thing that will be produced out of its parse method is indeed one of its. >> You're going to see a lot of these T-cells throughout here because they're often, it's about implementing an interface, but, I'm actually the generic parameter on this. This is something, this is a pattern we've used throughout it. >> You get strongly typed results. You saw the same with the admin over the addition operator. You don't want to just get some interface result back because then you lose your strong typing. You want to be where you thread the strong types through the interface. >> This is fantastic. There are other features we could show here. I think static, abstract, and interface is one of the things I'm very excited about it because I feel like that whole embedding factories almost into the language in that sense. These static abstract factories, is something that I'm really excited to see what people go and do with it. We've done the generic math piece, but this is something that much more flexible to see what nixed libraries, we see that do very interesting things from serialization and all stuff. >> This feature excited. It's super open-ended. We thinking about design patterns, for instance. We saw that factory, it was an abstract factory. But it was also a static factory. It takes those two classic design patterns and puts them together and gives you something that combines the power of both. I wonder where else people are going to find that application. This is really one that we're going to see uses that we had never thought of and that, I'm going to just be explicit and beautiful. This is raw new expressive power. >> I'm blown away by it. But let's take a step in a different direction. We can talk a little bit about. We talked earlier about required properties and how we continue to refine and evolve larger features in the language. Another one that we've been consistently doing that with over many releases. I think most releases since C# 7 is pattern matching. >> Pattern matching, which is this gift that keeps on giving. In C# 7 we added pattern matching for the first time. It did just a few key things, but already then it was like really, it was opening up a new way of working with different shapes of objects that was more declarative and had less confusing if analysis and casts and so on. >> For me when we first did it, I thought it was a really great moment of design where we use the keyword, which was already technically pattern matching. We were saying, well, if it's this type, well now is it this type and I can give it a variable? Or is it this type and its length of two or something like that? That's something that, I feel like that's caused that keyword which has been there since C# 10 to continue to evolve and get more powerful. We've introduced and we do the same thing with the switch statement, but introduced switch expressions. How might I do this? This is a pretty reasonable implementation of this. But I think it would be interesting to try and do this with pattern-matching. >> Let's try to do it with pattern matching. Essentially we want to do is switch expression. Instead of all this imperative logic, let's try to go all out and do this declaratively with a switch. >> This is the nerdiest way to do it. Let's do it this way. >> Yes. >> To be able to match on an array is a trick. We could match and say this array has a length of zero or something like that. >> Up until now we haven't really had patterns for things that are list-like. You want to talk about the elements of the incoming thing. That's what we can do now with list pattern. You can say, for instance, and we use square brackets for that, is this an empty thing? In that case, return zero, except it has to be T.Zero but then if it has something, what is that? Let's say it has one thing. >> We can use a recursive pattern here and say, it's one thing and we'll pull that first thing out of it using a var pattern. >> That could be any pattern in there. We can say if the first one is null, then do this. We'll use the var pattern here and then it's just that. >> Then we can just have a contest, I suppose, to see what gives up first the compiler's ability to process the size of this file or to produce cases for it and we can just keep on going. Because this is telling me that, hey, I haven't covered length three yet, so I've got a ways to go. >> It's not sustainable to keep adding more things, but we need a way essentially to say the rest, what we haven't talked about yet? >> Similar to range expressions, we use dot, dot here. O that means instead of just the second element, it means match the first element, put it in here, and then all the rest of the things put them in this variable. We should probably call this something else like rest. Now this is another array which contains the rest of the elements. >> This actually uses the slicing that we introduced in C-Sharp 8. >> I can be very clever and now I can make this recursive. That feels good. Although one thing, but you were just about to point it out too, is that it feels like now we don't really need the second one. >> Let's start to swap them around and see what happens. Now we get an error saying we'll never get here. >> Because it's subsumed by the branch above. That's awesome, by the pattern above. That's great. >> Pattern-matching telling you it's doing more in-depth analysis of what you can do. It's giving you feedback when your pattern-matching is off. >> I would say that though one thing about this as a problem is that it's slow. This is now an allocation factory. We're allocating new arrays. >> This is using slicing on arrays which is not the best. >> But we have ways of doing that and we can use a span right here and then we can come in and also say use a span right here and now you'll see that this thing is sliceable and therefore, we can get another span as the rest of it and we're no longer. >> Slicing spans is cheap. >> Yes. >> It's just looking at the same error. Very cool. >> Very cool. >> That's one little sleeper feature we should get too before they tell us to leave the stage. >> I just started a bill to show that it does run. Next up, then let's talk about this last sleeper feature. >> String literals in C-Sharp. Great for Shakespeare, not so great for JSON or XML. >> If I run this, you can see how it prints, but I had to come in here. When you copied and pasted this, you had to come in and escape these quotes, you can make it a verbatim string, but then you still have to escape the quotes by putting two double quotes. It's really annoying. >> New string literals that we call raw string literals, and they are the ones that have no escapes in them whatsoever. >> It's limited by three. >> Yes. >> Exciting. Maybe if you look close, you can see that the colorization on this went away because those are no longer escaping double quotes. Those are now part of the content. >> They're part of the content. Everything in there is part of the content, but Dustin, that someone would say, what if you want three double quotes in your content? What if you pay something and it has three double quotes? Then it's going to get confused. >> Yeah. Then it gets confused and this now ends it and that's a problem. In the spirit of C-sharp 11, I would say just add one more. >> Yes, take it to four. >> Take it to four. You can do exactly that. >> You can always contain any content by just putting more double quotes around it than it needs. >> We can also make these multi-line by introducing, but there's one restriction that this guy has to be on its own line. We will clean up the front and the back of that. If I come in here and run this, you'll see that this is now multi-line but this is always annoying too, doing multi-line. >> They go to the margin. >> They always go to the margin. >> If this were in a method body, I would be slamming this against the left side to try and strip the left, or maybe I was clever and wrote code to do that, which seems also not in the right direction, but I can indent these just fine. If I also indent the [inaudible], you can see this little line if you can make that out. What that's doing is that's showing you where it's going to trim the left margin. >> This has a left-margin trimmer built-in, which you can control with the end quotes there. We're out of time. >> We are. >> But we should just mention here there is a story for interpolation of these guys as well. You want to copy-paste something and then start poking holes to compute values and insert their string representations. That's all there as well. With that, thanks for watching. Many more C-sharp features, go and play with it, and if you haven't already, send quick tweet so that we can get questions here. Right now from Richard Campbell over there in the corner. Richard, how are you doing? >> Nothing like language gigs for breakfast. I am Richard Campbell and we've got some great questions for Mads and for Dustin. I'm going to start with this one right here from J. Sakamoto, who was one of the first questions that came in asking is C-Sharp 11's required and init property effective for property injectors, like inject FooService Foo of get, init on my Blazor code? Because if I could get rid of the workaround null bang, I'd be a happy person. >> That's a very specific question. >> Highly specific platform question. >> Lazy people want their love, man. >> I would say go try it. >> But the C-sharp 11 feature shows up in Blazor. >> Exactly. I can't see right here without looking at it. >> It sounds like something you should try. Take it out for a spin. >> I would say if you've been writing null bang and that works today with an init-only property, I would say it almost certainly works to take the null bang off and do a required part. >> Some code brings you love, Dustin, and some doesn't. You guys have shown some great things. I'll be excited to take those all off for a spin. I hope J. Sakamoto does as well. Let's grab another fun one here. This is from a Mehran, whose name is upside down and he says, does the C-sharp 11 required keyword participate in inheritance too? Is it possible to override it? >> That is a great question because this was the source of 90 percent of our design discussion. >> There was a lot of discussion around this. >> Yes, it totally required Nessus inherited, so you're derived class will definitely also require your required things. We discussed to what extent should this be overridable and how granular should that override be. In the end, we said, we don't know that there are scenarios for very granular override. We put in an attribute called sets required members attribute. If you put that on a given constructor, then that is exempting that constructor from the requiredness of the member. Essentially, you can say this is a special constructor, like a copy constructor. This initializes all the things, even the required things. When this constructor is called, don't give them errors for not initializing. That was the override that we picked. We can always refine that later. There's a C-Sharp began already next year, but we want to see solid user scenarios to make it worth our while. >> That's exactly right. >> Great question. >> I really appreciate all the thoughts you guys have on these particular problems. Watching your presentation hippie right away this, how many of these features that you get to show today you've actually been working on for years? I know that you put out C-sharp 11 just this time last year, but I got to think some of the things I saw today, especially around generics, we've worked on for a long time. >> The Abstract Virtual statics, the abstract statics and interfaces, that feature was actually prototyped the first time over a decade ago. That was back when it was all the classic.NET runtime and we didn't have the same ability to evolve the runtime. This really needs tinkering with the runtime itself, not just with the libraries or compiler. We couldn't do it back then, so we had to not do it. It's been on the radar for that long. >> It occurs to me during the history of.Network generics have been part of.NET since the very beginning. They were part of the original specifications written in the late '90s. It is cool to see these things that still surfacing that were part of the thinking right at the very beginning. >> Essentially we're trying to stick with the spirit of C-Sharp. The really core ideas that were there from the beginning, we keep trying to refine those, and we keep trying to do our design in the spirit of those, even as we take C-Sharp in a direction certainly of more terseness and brevity make it feel more lightweight and more approachable for new adopters as well. We try to keep those core concepts, rally around those, rather than slam things in. >> Well, Mads, Dustin, you guys hit me hard first thing in the morning. I'm glad I had a cup of tea early because you got me thinking about a lot of stuff. Thanks so much for putting this great presentation together.
Info
Channel: dotnet
Views: 24,753
Rating: undefined out of 5
Keywords: .NET, C#, Deeper .NET, group-deeperdotnet
Id: H18CfoinPZg
Channel Id: undefined
Length: 30min 28sec (1828 seconds)
Published: Fri Nov 11 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.