>> [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.