0:34 - 5:34 Nullable reference types 5:35 - 7:48 Async streams 7:49 - 8:46 Array slice Thank you and best wishes to you and your team Mads, happy holidays from Aarhus.
i used javascript,python,php,java. But i enjoyed alot to work with C# in its own best IDE visual studio. C# gives real understanding how programming language work in more disciplone way. Thumbs Up guys and Thank you for your great gift of C# 8.0.
For some edge cases in math, F# is a bit more capable. But that edge seems to get smaller and smaller and maybe in the future F# will only really be useful for very abstract stuffs or for those who just hates brackets.
@A Hero Academia if you mean Electron apps, it's not the future, it's just an unfortunate turn of events that the most broken language out there is the easiest to port to different desktop and mobile systems because every system has a web browser nowadays. Python though... as a prototyping tool maybe... but reimplementing anything in python? Where? Why?
Isn't it F# records? type Person = { FirstName: string; LastName: string } let person = { FirstName = "John"; LastName = "Connor" } Still have to specify the record labels though.
They say if you step on a cockroach it releases their eggs. In a sense the same as you would also get more bugs. Now the cockroach thing is a myth so does that make Microsoft a more anoying thing to deal with then? ^^
idontusenumbers i tried VS with ReSharper and it's great. Just can't shell out money for that. I tried IDEA using Kotlin. It's good as well but not as great as VS.
VS consistently lags behind IDEA and ReSharper. Every feature demonstrated in the recent VS 2019 preview has been in IDEA for at least 5 years. It's been that way pretty consistently with each release.
@@idontusenumbers depends on what you need, but the one thing that has been consistent as well is how bloated IDEA has been getting over the past few years. I guess more functional tools in the developers' arsenal also brings some negative consequences sometimes...
@@TheAndrejP what do you mean by bloated? It's driven by plugins; I have way more than the default set enabled and it loads fast, is very responsive, and never crashes. Visual studio feels more boosted to me and I can't turn of nearly as much.
The way this team executes on adding new features to this language is really excellent. I remember Anders talking about non-nullable reference types years ago, and they figured out how to do it in such an elegant way. Good stuff!
On the CLR Yes but not overall....look at kotlinlang.org/ Now they have taken inspiration from Java 8 Default methods on interfaces and null check from Kotlin.
but if you define "elegant" as "work horse for 9-18 job with some cool features you can tinker when you need to spend those 30minutes before next useless meeting" then it is!
These features look amazing. I've been following the more abstract discussions on csharplang, but actually seeing the features used in a project is so much cooler.
yeah, but the syntax is horrible, why not just use the python syntax??? Too proud to admit it's better? array[1:2], array[:2], array[:-2], array[-3], etc... so much better!
Non-nullable references, null-warnings for nullable references, async streams, better inference for new, and FINALLY switch expressions with patterns and exhaustiveness checking. C# is getting more and more functional, and taking notes from other functional and functionally-inspired languages like Scala, MLs, Haskell, or Rust (or F# ;P) Hoping C# will get something similar to Rust's Enums (like type-safe tagged unions) or Scala's Case Classes. All these code readability, expressiveness, and conciseness improvements, in addition to type-safety improvements (null is now completely a type-system thing) really make C# a language I _WANT_ to code in. And that's from a usually mainly Linux guy who mostly codes in C, Python, JavaScript and Rust, and usually only C# at internships.
Don't forget if you don't like a feature (like default implementation in an interface) then you don't have to use it. Been developing C# apps since 2006 and I've very rarely used abstract classes, as they're not something I like tying myself to.
That only works if you're not part of a team! Default interface implementations are mixin of a interface and an abstract base class. It creates lazy developers and it takes away the concept of a blueprint! It is a terrible idea and I hope it can be turned off in a solution-wide manner or stop compiling when MSBuild encounters such a construct.. Changing existing interfaces should not be taking lightly. One should really reflect why such a change is necessary. Often a derived interface works just as good and otherwise you should do the work and fix the implementations that are broken by the interface change.
@@MiningForPies That is probably because you are only part of a team and not managing a team. I'm a software architect and one of my job is to enforce our coding standards, rules and conventions. StyleCop(.Analyzers) have (currently) only support up to c# 7.3. So, if a new intern (which watched this episode and thinks this is a quick way to extend interfaces (we follow SOLID principles, so basically everything (even entities, but that reason lies in our MongoDB ORM) is a interface), I currently have no way of stopping him, even when the coding standards say that default interface implementations are not allowed. If you want to use the concept of default interface implementations in new code, you can define a normal interface and create a (abstract) base which marks all methods and properties as abstract. Need to be implemented explicitly by every concrete implementation. Than when you introduce a new method to the interface, you can add a virtual method to the base class and all implementations that inherit from that base class will have that default implementation. Concrete classes that implement the interface, but not inherit from the base class will still break. Sounds very much like the concept of a default interface implementation. Except that if I create a new concrete implementation of the interface, it is MY decision to inherit from the base class. However, when I choose NOT to use the base class, the developer that made the interface change, will need to consult with the authors of the broken implementations, if the implementation in the base class can be copied to the broken implementation. C# will not suddenly 'add' a default implementation to my class. This is a very important architectural standpoint.. But I'm sure that once C# 8 is officially released, StyleCop gets an update as well, so I can enforce that default interface implementations never makes into TFS because it is stopped by the checkin rule..
You can't everything peer review. Well, you can, but than you won't make your deadlines. Style cop is a very good solution to enforce coding standards, rules and conventions. It is very simple, if you can't commit (or shelve) a default interface implementation to TFS, there is also no need for a peer review! Do you have any idea how much time this saves? Also peer reviews usually examine the requested feature, they spend almost no time checking if you did follow all the coding standards, rules and conventions.. We have written our own ORM toolkit. Let's say you have a product entity. Magento requires different fields than Prestashop, Amazon or SalesForce. So, we have a 'base' order entity and each shop specific implementation add it own fields. So you have a Product, MagentoProduct and AmazonProduct entity. So why the interfaces. Converting product into AmazonProduct and MagentoProduct is very resource intensive because of the casting to concrete types. That is why we use interface entities. So, you also have IProduct, IAmazonProduct and IMagentoProduct interfaces. With the use of the reflection magic we're able to dynamicly create a 'super' entity that implicit implement IProduct and explicitly implement the addon product interfaces. This super entity has all three implementations, so passing the super entity as IMagentoProduct or IAmazonProduct is possible without casting. You don't get passed a AmazonProduct anymore. Within product document each addon has it's own section addon_{addonid}_{entityname}. The super entities than for example has a property Addon_{addonid}_amazon_product_sku which explicit implements IAmazonProduct.Sku. But the same entity can also hold a Addon_{addonid}_Magento_product_sku which implements IMagentoProduct.Sku. Developers don't have to create these super entities. The system does that for them, but because you don't get your original interface implementation passed to your addon, you need to use the entity interface. Also the 'I' from SOLID stands for Interface Segregation Principle which states that you should only program against interfaces. Interfaces are also very easy to mock and fake and that makes unit testing a breeze.. SpecFlow is used to 'prove' to the customer the code is working as described (not as hoped). That is next to the regression tests and e2e intergration tests. Writing code is at max 25% of the time spend by a developer. Writing unit tests takes at least as much time writing. Than you get the BDD and E2E tests, updating documentation, manual testing and communication (with team members or stake holders). Remember done is done. For example when we need to asses how much time developing a certain feature costs, we simply multiply the 'raw' development time by six. The first four multiplications are for the development team, the 5th for the account manager and the 6th is basically spare time. When your 3 days late, the customer is mad. When you're 3 days early, the customer throws you a parade.. We like parades!
"switch" is a statement and not a function, and so it cannot return any value. The return statement requires for the value that will be returned to be explicitly specified, stored in a variable or returned by another function. Your way of writing the recursive pattern is similar to a function call while the presented way is similar to an anonymous function with a switch statement inside it. If you use it like that, it would be very easy to confuse the switch statement with a function.
The only thing that I am not comfortable yet it with the 'Default Interface Members'. If you give a body to the interface, now it is no longer an interface, but sort of an abstract class having the new members implemented and the old ones as abstract members (sorta!). I am still trying to convince my self that it is a good idea.
I understand why they choose to make the nullable reference types feature a thing that must be enabled - I generally like opt in stuff. But personally i would have liked this one to be the other way around. When creating a new project i have to enable a feature that (at least to me) makes sense to always have enabled - That seems wrong. If it was the other way around then when upgrading i suddenly get a lot of warnings (remember your code will still compile and run) I can then choose to say i don't care and opt out of the feature to remove the warnings.
I think we should probably have it on by default in new C# 8.0 projects. But people open and upgrade existing projects for many reasons, and many have "warn as error" on. We just can't break those scenarios. Maybe we can give an informational message telling them how many warnings they would get if they turn it on! :-D (only half joking)
I don't even use C# anymore but like watching these because they're always done so well. Microsoft has become my favorite company and I really hope they keep doing the amazing job they've done over the last 5 years.
From .NET 4.6 version you (Microsoft) are reading my thoughts. When I think It would be nice to improve coding in this part, you do it the next version. Thank you for your work.
@@ACogloc, Yes, Kotlin has these features for a while now, but so does F#. I use many different languages (for fun and profit) incl. Kotlin+Java and C#+F#; it's a good time to be a programmer. Maybe someone out there is having fun with Java, who knows?
Some great things. Really looking forward to the nullable reference types. This is an amazing thing that has been missing from the mainstream OO languages. Especially like the subtle yet clear and consistent syntax. I almost want it to give errors instead of warnings. Almost.
Some of the other languages have added the Maybe monad to their standard library. E.g. Option/Optional in Java/Scala. One advantage with this is that you can view e.g. Option as a container with zero or one elements. This means that you can use a nice linq-like chain expression on your optional instead of multiple if-statements that all check if the intermediate result is not null. Another advantage is that it is just a generic class that behaves like everything else in the type system, and not some special syntax or built-in feature in the language that complicates the language unnecessarily.
C# just keeps getting better and better. I'm very interested in Async streams. I have had recently developed something very similar to the example and it was a pain in the arse.
Mostly watched this because it's a joy listening to Mads talk about C#. Appreciate the adoption of more functional-style expressions. However, I'm curious what the C# team thinks about Data Oriented Design, as a game developer it's a big part of how we architect large titles.
6 ปีที่แล้ว +6
Amazing job. You are tracking and learning from new languages.
Some things I would like: * Inline classes (like kotlin) * readonly ref struct as default (the number of hoops I have to go through to get a safe, immutable and performant type is horrendous) * immutable as default, maybe introduce a new declaration for immutable variable: immut a = 10? And all recursive immutableness should follow through, like rust. * numeric generics * traits (default interface with operator overloading)
I really don't like the new default interface implementation feature. Feels like it will be misused by some. Probably in a project I will have to maintain in the future...
To avoid breaking things by extending the interface. Suppose you have an IPerson with FirstName and LastName, then you realise you need a MiddleName. Suddenly, anyone implementing an IPerson needs to make a change to avoid breaking their code by upgrading to the new version of your library. Of course it doesn't actually solve anything.
@@madstorgersen7881 Will we be able to search for all "implied" usages of these? So, using the logging example, will I be able to search for occurrences of "Log(Exception)" where it wasn't implemented, but where I might want to implement it piecemeal?
One I'd like to see is automatic assignment constructors for immutable types. Ideally something that would generate the Equals and GetHashCode overrides for a struct too. Right now the best way I've found of doing this is writing a T4 template for each struct and calling code to generate it based on the properties you want. I might go one step further and create something like an EDMX file to generate T4s to generate the structs but I have a feeling that by the time I've done this, it will already have its own syntactic sugar!
Very nice summary. One or two questions: this might be a bit of a philosophical can of worms, but what conceptually is the difference between the behaviors IAsyncEnumerable and IObservable? My view is that the "Enumerable" part is synonymous with "Iterable," but the async part simply means 'iterate when notified.' To my mind this is the same as an IObservable with one subscriber. Do IAsyncEnumerables allow multiple subscribers in some syntactically transparent way?
Is the addition of the await foreach supposed to basically replace BlockingCollection completely or is there something I am missing here ? Is there a situation where one would be used instead of the other ?
Awesome features! The nullable feature will be a pretty usefull tool to improve maintainability of the codebase, and i feel like c# is closely looking to languages such as python, looking at the improved tuples vrom c#7, and the index slicing of c#8 now. I love it! Even though i'm not a big microsoft fan, i love the .NET CORE abd c# projects, and i believe that they both have a very bright future seeing the awesome changes of last years.
Just amazing. I'm so disappointed that my University is teaching us Java (and old java at that), instead of this language. This will become the industry standard as soon as we have a reliable and nice x-platform .NET Standard, it will very likely replace C++ and Java in many application cases. It's slicker than anything I know, great job, and please keep this going. Also great to see you actually interacting with the community.
C# is the best hybrid language ever! Not only for its features and evolution, but also for its ecosystem of .NET (both, Framework and Core), IDE, tools, libraries and community. Plus, now we can have it running on the browser with WASM+Mono. COOL!! ...and thanks Mads, Anders, Dustin, Eric, Gafter, and all the other people that together created this masterpiece!
5:25 bug on line 29. Crash with IndexOutOfRangeException whenever the string is empty. But hey I'm sure your customer would be much happier with a crash due to IndexOutOfRangeException than with a crash due to NullReferenceException, right?
Great video! Thanks! That syntax is added to make some things just a little simpler makes me wonder if C# isn't just done now. I feel like it is the best language already as it is now and that you can still come up with new cool stuff amazes me.. Perhaps all these small things will make programming more difficult because there's more to learn for beginners to understand existing code. Am I getting old? Lol. Is there any big stuff coming in the future?
Hm... Interface can has methods now... (it it possible and in old versions with IL, but not easy) What general difference between interface and abstract class now? (except multi inheritance)
Ironically the code can still produce a array out of bounds exception when MiddleName is 'String.Empty'. Therefor the code should check for String.IsNullOrWhitespace or even better if length is greater than zero instead of just null...
Switch expressions are an amazingly welcome addition, I can think of a ton of situations in the past where it would have been very helpful. C# as a language is top notch, it's been my go to language for about 90% or so of my projects since 2003, as much as I can. Now if only the rest of the .NET ecosystem can catch up, there are a few gaps to close out there in the .NET Core world revolving around Roslyn Code Analysis, DLL unloading at runtime, and so on, some gaps over especially in the Unity3D world, of course that one's 3rd party, but I would really like to see Microsoft implement something 3D on the scale of Unity for serious app development as a replacement to UWP for heavier cross-platform UIs, since I'm constantly between my Windows desktop and a MacBook. I actually use Unity for mathematics in linear algebra, calculus, and trig, better than Matlab but requires reinventing a lot of wheels and Unity's UI is primitive compared to UWP XAML, plus they don't follow best practices in a lot of areas, last I checked even though they implemented System.Threading.Tasks.Task they didn't implement a way to dispatch on the UI thread. VS for Mac has got a bit of catching up to do in the OSX world, but actually not bad. I spent a tad bit of time in Python, and found that even though I didn't like a lot of things about Python or some of the development communities involved with it, they had some good iterators and data types that I thought would be useful in C#. Seeing array slicing on the horizon makes me feel at home a bit more.
Being a fan of switches, i'm surprised I liked the new option. but why not add a default, so you can just catch stuff you dont want to handle uniquely?
I understand why people who work in C# and .NET all the time are grateful for time-saving features. But for someone like me who only works with them on occasion, the extra functionality has been decreasing the language's readability and increasing the learning curve. I can write programs in C# because the fundamentals of the language are the same as other OOP languages that I use all the time. But I wouldn't feel comfortable interviewing for a job as a C# developer even though I've written the back end for my personal web apps with C# and ASP.NET (which in itself changes rapidly). It's very much a skill that if you don't work with it regularly, you fall behind because of how quickly it advances. I appreciate the power of the framework, but I have to consider my employment viability when picking technologies to use in my projects. And because my projects are desktop-style web applications that are 95% front-end work, I'll never be able to devote the steady time to C# and ASP.NET it takes to maintain marketable skills. Anyway, you guys are clearly doing great work. I just wish it was something I could justify investing my time in.
I know dude... you gotta have that black screen in a dark room while techno plays and you recline in a layback hacker chair with ceiling suspended monitors while matrix plays on the second monitor yelling "I'm in!" every time you run a debug
Ok so now the IEnumerable interface can finally be fixed by adding a CanReset property. Not as if Reset was a useful something but starting with C# 2.0 iterators it became completely useless as it was no way to query if it was implemented.
One thing I do not understand about the switch statement. Can we do something like this now? int x, y return (x, y) switch { (1, 2) => 3, (1, 3) => 5, default => CalculateDefaultXY(x, y); }
Just replace "default" with an underscore "_" and you got it. In general, you can use the underscore to specify that the expression in that syntactic location can be anything. e.g. you could have another case that looks like (3, _) => 7 if you wanted to map every tuple with x=3 to 7.
hmm, can I opt in for specific Fields to be non-nullable? That'd be way sweeter imho. I don't like the #nullable enable. I would prefer it to be similar to an Attribute
I can imagine it was a tough decision when every currently implemented string is nullable without the ?, but it would be kind of silly not to use the ? as the notation for a nullable type when that is what is used for all other nullable types. Imagine having to keep track of different ways to make nullable variables depending on the type!
@@Gunnerpunk I don't think it'd be that chaotic. Let's say we mark a variable as *public string~ name;* it'll be non-nullable *public string name;* would be nullable *public int~ age;* would be synonymous to *public int age;* *public string? name;* would be synonymous to *public string name;* We can of course discuss about the marker character. Or maybe mark it as non-nullable like this: *[NonNullable]* *public string name;* Unfortunately it'll be an attribute, it'd be difficult to implement it in a way that throws compiler like shown in the video
I think you put it in a scope instead... Also if you only want some fields be non-nullable then just nullable all the other fields. It's probably a good idea to specify what's nullable rather than what's not anyway, because something being nullable will be harder to process than something that guarantees non-nullable.
I enjoyed most of the new features. My only concern is about default methods in Interfaces. I found it a horrible solution when it was first presented in Java 8 and I still have the same opinion now regarding to C#. I can understand the motivation, but ins't extension methods a more elegant solution? The idea of default methods in interfaces sounds to me like a tech debt that Java and C# designers insist in not solving: allowing multiple inheritance.
This allows for the safe kind of multiple inheritance. Also, extension methods are not virtual (meaning they cannot be overridden) which is a massive downside.
If you have to write an extension method just to bring default implementations then it creates some other hassle, also you can't override it because "it's not part of the interface". I think such feature is more of "bringing something that can be safely ignored without issue if you don't care", while both abstract classes and multi inheritance suggests that you have to take care of it and avoid breaking it. Also, since C# works in the .net framework/core, you would have to wait for that to update until the chance of multi inheritance happening would appear
Regarding switch expressions, why couldn't the compiler just infer the datatype from what was being passed in, then it would be even cleaner looking, and just have variable names or null?
@@lionkor98 I'm sorry, I don't understand. I learned more that the switch expression can do casting evaluations. I was interested in a multiple string parameter expression that didn't involve repetitively declare the type being passed down.
An abstract class can have constructors and fields, making them a true class. Interfaces can only have method bodies, meaning they are still just contracts (they don't dictate any internals of the implementing class)
0:34 - 5:34 Nullable reference types
5:35 - 7:48 Async streams
7:49 - 8:46 Array slice
Thank you and best wishes to you and your team Mads, happy holidays from Aarhus.
Sergiu Talnaci MVC (Most Valuable Comment)
Thanks Mate
Thanks god. It helps to save the video. LOL
what a convenient comment
Async Streams .. .Beautyyyyyy
i used javascript,python,php,java. But i enjoyed alot to work with C# in its own best IDE visual studio. C# gives real understanding how programming language work in more disciplone way. Thumbs Up guys and Thank you for your great gift of C# 8.0.
Thanks for the kind words!
For some edge cases in math, F# is a bit more capable. But that edge seems to get smaller and smaller and maybe in the future F# will only really be useful for very abstract stuffs or for those who just hates brackets.
The switch expressions look so clean, basically like a truth table. Thats awesome!
It is an amazing time to be a C# programmer!
Good times indeed!
@A Hero Academia Not really. I've been doing Java n Js for a little over 2 years and I humbly admit that C# is the future
@A Hero Academia if you mean Electron apps, it's not the future, it's just an unfortunate turn of events that the most broken language out there is the easiest to port to different desktop and mobile systems because every system has a web browser nowadays.
Python though... as a prototyping tool maybe... but reimplementing anything in python? Where? Why?
@@PhillipMwaniki Flutter and Dart are the future
@@nosmirck Typescript already ate Dart alive.
C# 10.0 will read your mind:
var person = new ("John", "Connor");
You also can do Person p = ("",""); trick with ValueTyple and implicit conversion
@@namelastname4077 Then we can
var person = new (Encoding.ASCII.GetString(Convert.FromBase64String("JTI4LiUyMCUyOSUyOCUyMC4lMjk=")));
@@ahdungai8489 I think that the compiler would be able to optimize this and so block It.
new should be optional
Isn't it F# records?
type Person = { FirstName: string; LastName: string }
let person = { FirstName = "John"; LastName = "Connor" }
Still have to specify the record labels though.
first 4 minutes is programming life in a nutshell... gets a bug, solved it.... puts in feature, gets 10 more bugs
I found it really amusing, too, lol
and we solve all the bugs until we get a running code lol
They say if you step on a cockroach it releases their eggs. In a sense the same as you would also get more bugs. Now the cockroach thing is a myth so does that make Microsoft a more anoying thing to deal with then? ^^
Just can't leave C#. The best modern programming language paired with the best IDE.
Rider? VS with ReSharper? Have you used IDEA?
idontusenumbers i tried VS with ReSharper and it's great. Just can't shell out money for that. I tried IDEA using Kotlin. It's good as well but not as great as VS.
VS consistently lags behind IDEA and ReSharper. Every feature demonstrated in the recent VS 2019 preview has been in IDEA for at least 5 years. It's been that way pretty consistently with each release.
@@idontusenumbers depends on what you need, but the one thing that has been consistent as well is how bloated IDEA has been getting over the past few years. I guess more functional tools in the developers' arsenal also brings some negative consequences sometimes...
@@TheAndrejP what do you mean by bloated? It's driven by plugins; I have way more than the default set enabled and it loads fast, is very responsive, and never crashes. Visual studio feels more boosted to me and I can't turn of nearly as much.
Was using Python yesterday for Advent of Code and thought that it would nice if we got array slicing for C#. Nice timing lol. Looks good!
The way this team executes on adding new features to this language is really excellent. I remember Anders talking about non-nullable reference types years ago, and they figured out how to do it in such an elegant way. Good stuff!
I am profoundly thankful to the past me who decided to learn C# instead of *other languages*
I'm glad you learned C#! Don't hesitate to learn more languages too!
I agree especially with Blazor web assembly looming and now open source WPF
@Gerardo Gonzalez This.
well you would think differently if you'd also learned C++23
You should learn more languages. Pretty much all these features are variations on what other modern languages already have.
I think C# is the most elegant language out there today.
Definitely not elegant. "random" weird operators here and there and on a per-feature implementation does not make for an elegant language.
On the CLR Yes but not overall....look at kotlinlang.org/ Now they have taken inspiration from Java 8 Default methods on interfaces and null check from Kotlin.
but if you define "elegant" as "work horse for 9-18 job with some cool features you can tinker when you need to spend those 30minutes before next useless meeting" then it is!
OCaml would like to have a chat with you
Maybe there is too much boilerplate in C# but yeah it's a pretty nice language. I would be happier with some "global using" feature.
These features look amazing. I've been following the more abstract discussions on csharplang, but actually seeing the features used in a project is so much cooler.
Where is C# going? This is so absurdly good that I cannot believe all these are real (beginning from C# 7.0).
Glad you like it! :-)
Imagine how I feel. I started in VB5 🤪 no seriously though. C# is blowing my mind past few years
@@PiotrKula1 and still VB6 are much faster than this
C# is transforming from an Application Programming Language (Line of business "apps") to a Systems Programming language (OS)
Array slicing, FINALLY!!!!
How is that useful enough?, may be video games?
@@focl2003 It's useful for a million things, I'm using it when getting data from an array that contains FFT of audio
@@greenvm It should be, y use linq everywhere but I know it's not that low level.
yeah, but the syntax is horrible, why not just use the python syntax??? Too proud to admit it's better? array[1:2], array[:2], array[:-2], array[-3], etc... so much better!
But the range end is implicitly exclusive and can't be changed. D:
Thank you guys for taking such good care of us. :)
Nullable-reftypes are amazing, thanks for that.
That feature is actually more of "non-nullable-reftypes" because everything used to be defaulted to be nullable :)
Non-nullable references, null-warnings for nullable references, async streams, better inference for new, and FINALLY switch expressions with patterns and exhaustiveness checking.
C# is getting more and more functional, and taking notes from other functional and functionally-inspired languages like Scala, MLs, Haskell, or Rust (or F# ;P)
Hoping C# will get something similar to Rust's Enums (like type-safe tagged unions) or Scala's Case Classes.
All these code readability, expressiveness, and conciseness improvements, in addition to type-safety improvements (null is now completely a type-system thing) really make C# a language I _WANT_ to code in.
And that's from a usually mainly Linux guy who mostly codes in C, Python, JavaScript and Rust, and usually only C# at internships.
Great new features Mads, all of it is stuff I've always wanted. Keep elevating C# to new levels and bringing us more awesome stuff to play with.
Wow! These are awesome additions. I like the way C# is going!
I can foresee default interface implementations being badly abused.
I though that too... This is just virtual methods all over again. But the other features were amazing, specially switch expressions
Don't forget if you don't like a feature (like default implementation in an interface) then you don't have to use it.
Been developing C# apps since 2006 and I've very rarely used abstract classes, as they're not something I like tying myself to.
That only works if you're not part of a team!
Default interface implementations are mixin of a interface and an abstract base class. It creates lazy developers and it takes away the concept of a blueprint! It is a terrible idea and I hope it can be turned off in a solution-wide manner or stop compiling when MSBuild encounters such a construct..
Changing existing interfaces should not be taking lightly. One should really reflect why such a change is necessary. Often a derived interface works just as good and otherwise you should do the work and fix the implementations that are broken by the interface change.
@@2Fast4Mellow I've worked in huge teams and never had an issue.
@@MiningForPies That is probably because you are only part of a team and not managing a team. I'm a software architect and one of my job is to enforce our coding standards, rules and conventions.
StyleCop(.Analyzers) have (currently) only support up to c# 7.3. So, if a new intern (which watched this episode and thinks this is a quick way to extend interfaces (we follow SOLID principles, so basically everything (even entities, but that reason lies in our MongoDB ORM) is a interface), I currently have no way of stopping him, even when the coding standards say that default interface implementations are not allowed.
If you want to use the concept of default interface implementations in new code, you can define a normal interface and create a (abstract) base which marks all methods and properties as abstract. Need to be implemented explicitly by every concrete implementation. Than when you introduce a new method to the interface, you can add a virtual method to the base class and all implementations that inherit from that base class will have that default implementation. Concrete classes that implement the interface, but not inherit from the base class will still break.
Sounds very much like the concept of a default interface implementation. Except that if I create a new concrete implementation of the interface, it is MY decision to inherit from the base class. However, when I choose NOT to use the base class, the developer that made the interface change, will need to consult with the authors of the broken implementations, if the implementation in the base class can be copied to the broken implementation. C# will not suddenly 'add' a default implementation to my class. This is a very important architectural standpoint..
But I'm sure that once C# 8 is officially released, StyleCop gets an update as well, so I can enforce that default interface implementations never makes into TFS because it is stopped by the checkin rule..
@@2Fast4Mellow tools like style cop should never, ever, replace proper peer reviews.
It sounds like a nightmare forcing everything to be an interface.
You can't everything peer review. Well, you can, but than you won't make your deadlines. Style cop is a very good solution to enforce coding standards, rules and conventions. It is very simple, if you can't commit (or shelve) a default interface implementation to TFS, there is also no need for a peer review! Do you have any idea how much time this saves? Also peer reviews usually examine the requested feature, they spend almost no time checking if you did follow all the coding standards, rules and conventions..
We have written our own ORM toolkit. Let's say you have a product entity. Magento requires different fields than Prestashop, Amazon or SalesForce. So, we have a 'base' order entity and each shop specific implementation add it own fields. So you have a Product, MagentoProduct and AmazonProduct entity. So why the interfaces. Converting product into AmazonProduct and MagentoProduct is very resource intensive because of the casting to concrete types.
That is why we use interface entities. So, you also have IProduct, IAmazonProduct and IMagentoProduct interfaces. With the use of the reflection magic we're able to dynamicly create a 'super' entity that implicit implement IProduct and explicitly implement the addon product interfaces. This super entity has all three implementations, so passing the super entity as IMagentoProduct or IAmazonProduct is possible without casting. You don't get passed a AmazonProduct anymore. Within product document each addon has it's own section addon_{addonid}_{entityname}. The super entities than for example has a property Addon_{addonid}_amazon_product_sku which explicit implements IAmazonProduct.Sku. But the same entity can also hold a Addon_{addonid}_Magento_product_sku which implements IMagentoProduct.Sku.
Developers don't have to create these super entities. The system does that for them, but because you don't get your original interface implementation passed to your addon, you need to use the entity interface.
Also the 'I' from SOLID stands for Interface Segregation Principle which states that you should only program against interfaces. Interfaces are also very easy to mock and fake and that makes unit testing a breeze.. SpecFlow is used to 'prove' to the customer the code is working as described (not as hoped). That is next to the regression tests and e2e intergration tests. Writing code is at max 25% of the time spend by a developer. Writing unit tests takes at least as much time writing. Than you get the BDD and E2E tests, updating documentation, manual testing and communication (with team members or stake holders). Remember done is done. For example when we need to asses how much time developing a certain feature costs, we simply multiply the 'raw' development time by six. The first four multiplications are for the development team, the 5th for the account manager and the 6th is basically spare time. When your 3 days late, the customer is mad. When you're 3 days early, the customer throws you a parade.. We like parades!
Can someone explain to me why not write instead :
return switch (p. FirstName, p. MiddleName, p. LastName) {
...
}
Sounds more intuitive to me.
"switch" is a statement and not a function, and so it cannot return any value. The return statement requires for the value that will be returned to be explicitly specified, stored in a variable or returned by another function. Your way of writing the recursive pattern is similar to a function call while the presented way is similar to an anonymous function with a switch statement inside it. If you use it like that, it would be very easy to confuse the switch statement with a function.
The only thing that I am not comfortable yet it with the 'Default Interface Members'. If you give a body to the interface, now it is no longer an interface, but sort of an abstract class having the new members implemented and the old ones as abstract members (sorta!). I am still trying to convince my self that it is a good idea.
Very good explanation of the new language features. Thanks for the video!
I love how C# is getting better and better every year!
F#: hey look at my clean code!
C#: IT'S MINE NOW
The Case Expressions are awesome!
I understand why they choose to make the nullable reference types feature a thing that must be enabled - I generally like opt in stuff.
But personally i would have liked this one to be the other way around.
When creating a new project i have to enable a feature that (at least to me) makes sense to always have enabled - That seems wrong.
If it was the other way around then when upgrading i suddenly get a lot of warnings (remember your code will still compile and run) I can then choose to say i don't care and opt out of the feature to remove the warnings.
You could just add that compiler directive to your c# class template so every class you create has it regardless of the project settings.
@@irwtla1 Thanks for the workaround but not really where i was going with my message :)
I think we should probably have it on by default in new C# 8.0 projects. But people open and upgrade existing projects for many reasons, and many have "warn as error" on. We just can't break those scenarios.
Maybe we can give an informational message telling them how many warnings they would get if they turn it on! :-D (only half joking)
@@madstorgersen7881 "CS4000: Not all warnings enabled"
A lot of the time non-nullable refs mean more code. I don't like them much since I am a careful programmer and I don't get null refs much.
I don't even use C# anymore but like watching these because they're always done so well. Microsoft has become my favorite company and I really hope they keep doing the amazing job they've done over the last 5 years.
Microsoft? Your favorite company? You poor, uninformed man...
@@carrott741 They are the tech giant I have the most favorable impression of, favorite company was the wrong words.
@@WolfersHD I see.
Happy to see these features in C# ...these have been present in Scala long long back...I'm happy for both the languages boasting these
From .NET 4.6 version you (Microsoft) are reading my thoughts. When I think It would be nice to improve coding in this part, you do it the next version. Thank you for your work.
3 dislikes from #JAVA people. I can understand your pain java people..
Eh, we've got Kotlin.
@@ACogloc yes java got a bunch of stuff from c# :D
They're finally getting local variable type inference...
@@ACogloc, Yes, Kotlin has these features for a while now, but so does F#. I use many different languages (for fun and profit) incl. Kotlin+Java and C#+F#; it's a good time to be a programmer. Maybe someone out there is having fun with Java, who knows?
@@TheAndreArtus C#, PHP, Java, C++, javascript, and I know VB
i can easily say the best language of this time!!
@Solve Everything dotnet core?
Nice, recuresive patterns and switch expressions looks cool and reminds me about Rust's pattern matching.
Some great things. Really looking forward to the nullable reference types. This is an amazing thing that has been missing from the mainstream OO languages. Especially like the subtle yet clear and consistent syntax.
I almost want it to give errors instead of warnings. Almost.
Some of the other languages have added the Maybe monad to their standard library. E.g. Option/Optional in Java/Scala. One advantage with this is that you can view e.g. Option as a container with zero or one elements. This means that you can use a nice linq-like chain expression on your optional instead of multiple if-statements that all check if the intermediate result is not null. Another advantage is that it is just a generic class that behaves like everything else in the type system, and not some special syntax or built-in feature in the language that complicates the language unnecessarily.
C# just keeps getting better and better. I'm very interested in Async streams. I have had recently developed something very similar to the example and it was a pain in the arse.
Thank you Microsoft. You guys are keeping us busy to learn new things and adding values to this technology world.
Mostly watched this because it's a joy listening to Mads talk about C#. Appreciate the adoption of more functional-style expressions. However, I'm curious what the C# team thinks about Data Oriented Design, as a game developer it's a big part of how we architect large titles.
Amazing job. You are tracking and learning from new languages.
We try. :-)
Some things I would like:
* Inline classes (like kotlin)
* readonly ref struct as default (the number of hoops I have to go through to get a safe, immutable and performant type is horrendous)
* immutable as default, maybe introduce a new declaration for immutable variable: immut a = 10? And all recursive immutableness should follow through, like rust.
* numeric generics
* traits (default interface with operator overloading)
I think last feature of interface break ISP principle , i think there is no need to add method body in interface
I really don't like the new default interface implementation feature. Feels like it will be misused by some. Probably in a project I will have to maintain in the future...
OMG MADS I'm so excited!!!
Me too!
Implicitly typed new-expressions. Best damn thing for sure, THANK YOU
I'm confused with the last feature (default interface members). Why would we need the ability to add a body to a function inside an interface?
To avoid breaking things by extending the interface. Suppose you have an IPerson with FirstName and LastName, then you realise you need a MiddleName. Suddenly, anyone implementing an IPerson needs to make a change to avoid breaking their code by upgrading to the new version of your library.
Of course it doesn't actually solve anything.
You can add a new member to the interface without breaking existing implementers.
@@madstorgersen7881 Will we be able to search for all "implied" usages of these? So, using the logging example, will I be able to search for occurrences of "Log(Exception)" where it wasn't implemented, but where I might want to implement it piecemeal?
Wasn't a big reason for having it interop with other languages/frameworks?
One I'd like to see is automatic assignment constructors for immutable types. Ideally something that would generate the Equals and GetHashCode overrides for a struct too. Right now the best way I've found of doing this is writing a T4 template for each struct and calling code to generate it based on the properties you want. I might go one step further and create something like an EDMX file to generate T4s to generate the structs but I have a feeling that by the time I've done this, it will already have its own syntactic sugar!
Very nice summary. One or two questions: this might be a bit of a philosophical can of worms, but what conceptually is the difference between the behaviors IAsyncEnumerable and IObservable? My view is that the "Enumerable" part is synonymous with "Iterable," but the async part simply means 'iterate when notified.' To my mind this is the same as an IObservable with one subscriber. Do IAsyncEnumerables allow multiple subscribers in some syntactically transparent way?
Is the addition of the await foreach supposed to basically replace BlockingCollection completely or is there something I am missing here ? Is there a situation where one would be used instead of the other ?
Awesome features!
The nullable feature will be a pretty usefull tool to improve maintainability of the codebase, and i feel like c# is closely looking to languages such as python, looking at the improved tuples vrom c#7, and the index slicing of c#8 now. I love it!
Even though i'm not a big microsoft fan, i love the .NET CORE abd c# projects, and i believe that they both have a very bright future seeing the awesome changes of last years.
Just amazing. I'm so disappointed that my University is teaching us Java (and old java at that), instead of this language. This will become the industry standard as soon as we have a reliable and nice x-platform .NET Standard, it will very likely replace C++ and Java in many application cases. It's slicker than anything I know, great job, and please keep this going. Also great to see you actually interacting with the community.
Are you from India?
C dev here to admit that C# makes me swoon.
C developers are the real programmer.
in 10:21 how can I apply a default case?
something like this
_ => string.Empty;
C# is the best hybrid language ever! Not only for its features and evolution, but also for its ecosystem of .NET (both, Framework and Core), IDE, tools, libraries and community. Plus, now we can have it running on the browser with WASM+Mono. COOL!! ...and thanks Mads, Anders, Dustin, Eric, Gafter, and all the other people that together created this masterpiece!
Check WebAssembly: Blazor
how to determine the 3rd item in the list has null property 1:36
I see the C# switch is finally catching up to the PowerShell switch and gaining ground on the match statement from F# :)
5:25 bug on line 29. Crash with IndexOutOfRangeException whenever the string is empty. But hey I'm sure your customer would be much happier with a crash due to IndexOutOfRangeException than with a crash due to NullReferenceException, right?
I personally like default interface member, it is useful for many of my use cases, thanks Mads for the sneak peak of VS2019
It would be nice to add extension methods to the interfaces that are inherited by their concrete classes.
Great video! Thanks!
That syntax is added to make some things just a little simpler makes me wonder if C# isn't just done now. I feel like it is the best language already as it is now and that you can still come up with new cool stuff amazes me..
Perhaps all these small things will make programming more difficult because there's more to learn for beginners to understand existing code. Am I getting old? Lol.
Is there any big stuff coming in the future?
Hm... Interface can has methods now... (it it possible and in old versions with IL, but not easy)
What general difference between interface and abstract class now? (except multi inheritance)
For the switch statements, what about numbers?
switch (int i, int j, int k)
{
{0, >0} => Log("all positive");
default: Log("default");
}
Default interface members looks and feels like abstract implementation , just a bit cleaner.
Can someone explain why we broke the pattern?
All these are nice. One thing I really want is making `new` keyword optional, like what Dart did
Can you make it possible to print which variable is null when you get that exception? would save a lot of time when debugging.
When will we have List slices, similar to array slices?
I really like those changes in foreach loop, makes life easier.
About the interface body:
How is the implementer informed about that new member? I guess with a colorized compiler warning or such?
Awesome work Mads!
Ironically the code can still produce a array out of bounds exception when MiddleName is 'String.Empty'.
Therefor the code should check for String.IsNullOrWhitespace or even better if length is greater than zero instead of just null...
So... the 'extension everything' feature won't be part of the release ?
Switch expressions are an amazingly welcome addition, I can think of a ton of situations in the past where it would have been very helpful. C# as a language is top notch, it's been my go to language for about 90% or so of my projects since 2003, as much as I can. Now if only the rest of the .NET ecosystem can catch up, there are a few gaps to close out there in the .NET Core world revolving around Roslyn Code Analysis, DLL unloading at runtime, and so on, some gaps over especially in the Unity3D world, of course that one's 3rd party, but I would really like to see Microsoft implement something 3D on the scale of Unity for serious app development as a replacement to UWP for heavier cross-platform UIs, since I'm constantly between my Windows desktop and a MacBook. I actually use Unity for mathematics in linear algebra, calculus, and trig, better than Matlab but requires reinventing a lot of wheels and Unity's UI is primitive compared to UWP XAML, plus they don't follow best practices in a lot of areas, last I checked even though they implemented System.Threading.Tasks.Task they didn't implement a way to dispatch on the UI thread. VS for Mac has got a bit of catching up to do in the OSX world, but actually not bad.
I spent a tad bit of time in Python, and found that even though I didn't like a lot of things about Python or some of the development communities involved with it, they had some good iterators and data types that I thought would be useful in C#. Seeing array slicing on the horizon makes me feel at home a bit more.
Love the AsyncEnumerables! C# has Observables now.
All is good but I have a bad feeling about method body in interfaces.
Didn't abstract people complain?
When will we have 'if' expressions?
Nice MONITOR bro.
Good presentation too
Awesome features!
"Default interface members" You are so close to real multiple inherence. Don't chicken out now!
That's hilarious. I was just reading about Lua mixins and was wishing C# had them...
We need a poster with all these improvements (preferably one that goes back to the older C# versions too)
Are you signing up to make one? :-D
I can’t wait till see what open source does for win forms.
Being a fan of switches, i'm surprised I liked the new option. but why not add a default, so you can just catch stuff you dont want to handle uniquely?
It looks like Kotlin! :D No disrespect. I think that's a good indicator that we're converging on good ideas.
When are you going to implement expression-ifs? the ternary operator is barely readable :C
Interesting features. Thank you.
This language only gets better!
I understand why people who work in C# and .NET all the time are grateful for time-saving features. But for someone like me who only works with them on occasion, the extra functionality has been decreasing the language's readability and increasing the learning curve. I can write programs in C# because the fundamentals of the language are the same as other OOP languages that I use all the time. But I wouldn't feel comfortable interviewing for a job as a C# developer even though I've written the back end for my personal web apps with C# and ASP.NET (which in itself changes rapidly). It's very much a skill that if you don't work with it regularly, you fall behind because of how quickly it advances. I appreciate the power of the framework, but I have to consider my employment viability when picking technologies to use in my projects. And because my projects are desktop-style web applications that are 95% front-end work, I'll never be able to devote the steady time to C# and ASP.NET it takes to maintain marketable skills. Anyway, you guys are clearly doing great work. I just wish it was something I could justify investing my time in.
White background..... Triggered!!!!!!
I know dude... you gotta have that black screen in a dark room while techno plays and you recline in a layback hacker chair with ceiling suspended monitors while matrix plays on the second monitor yelling "I'm in!" every time you run a debug
What a time to be alive.
Array slicing in C#? OH GOD THANK YOU!!!
You can already slice using LINQ stuffs, but having some sugar is good too, I think.
Async streams is going to be great. Been waiting for this for years.
Ok so now the IEnumerable interface can finally be fixed by adding a CanReset property.
Not as if Reset was a useful something but starting with C# 2.0 iterators it became completely useless as it was no way to query if it was implemented.
One thing I do not understand about the switch statement. Can we do something like this now?
int x, y
return (x, y) switch {
(1, 2) => 3,
(1, 3) => 5,
default => CalculateDefaultXY(x, y);
}
Just replace "default" with an underscore "_" and you got it. In general, you can use the underscore to specify that the expression in that syntactic location can be anything. e.g. you could have another case that looks like (3, _) => 7 if you wanted to map every tuple with x=3 to 7.
@@DrakePitts suddenly it got even cooler
hmm, can I opt in for specific Fields to be non-nullable? That'd be way sweeter imho.
I don't like the #nullable enable. I would prefer it to be similar to an Attribute
I can imagine it was a tough decision when every currently implemented string is nullable without the ?, but it would be kind of silly not to use the ? as the notation for a nullable type when that is what is used for all other nullable types. Imagine having to keep track of different ways to make nullable variables depending on the type!
@@Gunnerpunk I don't think it'd be that chaotic. Let's say we mark a variable as
*public string~ name;*
it'll be non-nullable
*public string name;*
would be nullable
*public int~ age;* would be synonymous to *public int age;*
*public string? name;* would be synonymous to *public string name;*
We can of course discuss about the marker character. Or maybe mark it as non-nullable like this:
*[NonNullable]*
*public string name;*
Unfortunately it'll be an attribute, it'd be difficult to implement it in a way that throws compiler like shown in the video
Maybe just use several interleaved sections with "#nullable enable .... _some fields _ .... #nullable disable" ?
I think you put it in a scope instead...
Also if you only want some fields be non-nullable then just nullable all the other fields. It's probably a good idea to specify what's nullable rather than what's not anyway, because something being nullable will be harder to process than something that guarantees non-nullable.
seems that C# 8.0 are getting some swift like feature. interesting
Some good work C# 8.0 is looking like Swift# :)
I enjoyed most of the new features. My only concern is about default methods in Interfaces. I found it a horrible solution when it was first presented in Java 8 and I still have the same opinion now regarding to C#. I can understand the motivation, but ins't extension methods a more elegant solution? The idea of default methods in interfaces sounds to me like a tech debt that Java and C# designers insist in not solving: allowing multiple inheritance.
As soon as either J or C# will finally implement MI, the other will follow suit. Can't wait for this to happen.
This allows for the safe kind of multiple inheritance. Also, extension methods are not virtual (meaning they cannot be overridden) which is a massive downside.
If you have to write an extension method just to bring default implementations then it creates some other hassle, also you can't override it because "it's not part of the interface".
I think such feature is more of "bringing something that can be safely ignored without issue if you don't care", while both abstract classes and multi inheritance suggests that you have to take care of it and avoid breaking it.
Also, since C# works in the .net framework/core, you would have to wait for that to update until the chance of multi inheritance happening would appear
Regarding switch expressions, why couldn't the compiler just infer the datatype from what was being passed in, then it would be even cleaner looking, and just have variable names or null?
so that it still works if you implement it in a base class, i guess?
@@lionkor98 I'm sorry, I don't understand. I learned more that the switch expression can do casting evaluations. I was interested in a multiple string parameter expression that didn't involve repetitively declare the type being passed down.
@@billrob458 You can use var. I don't know why Mads explicitly typed it in this demo.
@@MrRichiban Thanks Richard. I'll check it out.
Why still need to type new for that Person array elements?
Slicing was really cool!
So what's the difference between an interface with default implementations and an abstract class with virtual default methods?
An abstract class can have constructors and fields, making them a true class. Interfaces can only have method bodies, meaning they are still just contracts (they don't dictate any internals of the implementing class)
Great new additions.
But one thing I really wish C# would get is a robust Option type.