Yup, that's because Roslyn just wraps the top level code in a new static main method behind the scenes. The framework does not support top level statements, thus the C# parser modifies it to match the framework specifications (similar to linq queries which are converted to linq expressions since the framework doesn't know about them).
0:00 - Intro 0:55 - Getting started: Visual Studio version 1:46 - 1. Top Level Calls ... 4:23 - /* Note: Inline parameter name (VS feature) * / 8:43 - /* Note: .Net 5 vs .Net core * / 11:07 - 1. ... Top Level Calls 18:55 - Why top level calls? 23:20 - 2. Initial setter s 32:28 - 3. Known object type shorthand instantiation
40:36 - Recap and creating new demo Blazor app 42:30 - Demo Blazor app "fetch data" 44:17 - Improving Demo Blazor app "fetch data" code 47:45 - 4. Relational pattern matching in switch expression 54:18 - 5. Logical pattern matching in switch expression 1:04:24 - 6. "is not" pattern 1:08:30 - Recap 1:08:58 - Summary and concluding remarks; You did forgot to add timestamps tho. :D Cunning way to get me watch your videos out of order specified in "learning path".
Great stuff, man. Really learned a lot watching your videos. Just want to point out that the command line arguments still work in top-level programs. You can just use the variable `args` as you generally would in the more verbose setup and it works.
Ahh yes. Really makes it a lot more readable. And then its also possible to make VS studio show what the values being set in the constructor are called if you enable that feature.
No, as it is nothing new. Anonymous classes, Tuples or initializer list have been possible already. Btw. in OOP this case is super rare - except creating data based unit tests perhaps, but there you'll use edge corner data sets, and do not test with semantical equivalent data.
@@arneschneidermann8059 but this is not based on anonymous classes or tuples. Making a test dateset for unit testing should not really be a rare thing either. An anonymous class can be useful, same with tuples, but both should be avoided in most cases.
Top level calls is such an artificial change, probably introduced just to "keep up the appearance" against dynamic languages like Python. It doesn't even look in line with general best practices
4 роки тому+10
"is not" is now interchangeable with "!=" when comparing to constant values. Not only "null". Works: int n1 = 4; if (n1 is not 5) { System.Console.WriteLine("n1 is not 5"); } Does not work: int n1 = 4; int n2 = 5; if (n1 is not n2) { System.Console.WriteLine("n1 is not n2"); }
@@babri1402 you can already do: `if (myShape is Square mySquare)`, which creates a new variable "mySquare" which is a casted version of myShape using the Square class (if it's part of the hierarchy).
I'm sure we all will be used to that in no time...at least i wanted the logical patterns and the init setter long ago. The switch expression might be a bit tricky to get that in mind when it's time to use it :) I'm sure that Resharper will give me a hint like allways^^
I can't tell you how many times I tried to type out "is not null" before, "is null" was already there so it just made sense to me that I should be able to throw a 'not' in there. Switch expressions will make my life a lot simpler I predict as well.
Thanks for this video Tim, I like your manner of explanation. Just want to share my personal opinion about these features. 1. Top level calls: now I see less code which i never wrote))) it was always autogenerated by VS 2. Inline parameter names: it was in resharper long time ago and it is useful for me 3. Initial setter: my personal, it is not useful for me, due to you have to have reasons to make immutable property that's why private setter is better for me 4. Short hand instantiation: interesting one, but we already have "var" for shorten variable declaration 5. Switch expression: Best feature in this release! 6. Logical "is not" in conditions looks more intuitive, but in same time "!=" short and easy. Have a good day folks!
Good video Tim. I really hate where C# has gone in the past several years. Everything I liked about the language is being offset by dynamic features" that degrade it. If I want to code in JavaScript, I'll code in JavaScript. C# shouldn't try to be something it isn't.
Life, and programming, is about change. The market is changing and Microsoft is meeting the demands of that marketplace. The good news is that you don't have to use the newer features of the language. You can stick to what you like without a problem.
Thank you for sharing. One comment on using the Top Level Calls. I have been teaching C# and one thing the students found very difficult is to know where to insert code. This whole stuff with namespaces, classes, methods has a role, it is meant to create abstraction levels and is therefore very useful. In teaching C# console applications with all this boilerplate code can be very useful just to demonstrate how it works. Understanding a bit of how it works can be very helpful if you try to do more complicated things. And keep in mind, the project template will create this boilerplate code for you. So it just for readability,
Just a little tip: Disable Resharper if you have it before you start following along with the video. On my machine, this did not go well. Afterwards, you can re-enable it.
I really appreciate you coving all of this. I normally dont listen/read to too much on new features except stuff I am interested in. You successfully lured me in hook and sinker...lol I really like the new features in cSharp 9. The only problem I see is if a developer doesnt know the new stuff and they look at your code. They will be like WTH... how does that even work?
True, when folks jump in on the advanced topics, they can get lost. I try to point them back to my full teaching playlists where they can learn and build up to the level that this all makes sense. Please help get the word out on where to start - ua-cam.com/video/LUv20QxXjfw/v-deo.html
Professionally I've been away from C# for over a year, so this was really interesting to see. Some really useful features I'll be sure to use in my personal projects.
Great stuff. Really appreciate your work! I have been meaning to actually play around with the new features for a while now, this was a great first look. Can't wait for the video on records.
So, I'm going to type my thoughts as I watch: 1. Top Level Calls I understand the reasoning, but I'm to a big fan of this one. Considering that VS already does all the ceremony for you, its easier to just write inside main than to delete all and write top-level. Also, I don't think it makes it easier to read, I think it makes it harder. Reason being that you use that same namespace->class->method structure in basically every file, why would your Program.cs be any different? Its breaking the pattern and that makes it confusing. Also, most C# developers will soon in their careers get used to the extra ceremony to the point of not even noticing anymore. 2. Initial Setters That's a cool feature, but I bet i'm not gonna remember to use it. Similar to things like internal, where I know it exists, I know what its use case, but I rarely use it and often find out that the method I thought it could be internal, actually has to be public for me to include it in the interface. 3. Known Object Type Shorthand Instantiation Not a fan of this either. I likely won't use it for the same reason I don't like to use var. First of, with intelllisense, typing the class name for a second time can be done in 2 or 3 keystrokes, no matter how big the name is. Secondly, var can cause a lot of problems. Lets say you do var p = new PersonModel(), instead of PersonModel you could have anything else in there and var would accept it. By having to type it twice, you are twice as likely to notice in case you are instantiating the wrong class. That can become even more dangerous if, in the future, you decide to change that line to var p = MyFunction(). If your function doesn't return the correct type, var will take it anyway and may only notice when something goes wrong at runtime. Similar reasons apply to this shorthand, but without the benefits of var, so I'm likely not going to use it. 4. and 5. Relational and Logical Pattern Matching in Switch Expression I absolutely love that. I've always thought that switch statements are a underused feature of many programming languages and one of the main reasons for it is its limitations. Being able to do switch expressions with continuous and infinitely varied values with a notation that is even easier then regular switch statements is a very good feature that allows us to make much more readable code.
1. I covered top-level calls in another comment, but the gist is that the namespace, class, and method names don't apply to the Main method in the same way they do anywhere else in C#. You can't call Main (you would cause an infinite loop) so we have something that is in Intellisense but we have to know not to call it. That's where I see it being a big deal. I can easily see the templates being updated to use this top-level syntax going forward. 2. I can see forgetting something if you don't use it all the time. I don't think this is a huge feature, but it is a big deal in specific situations. 3. Couple of things here. First, var does not allow a type change unless you physically change the type assigned to it. I don't see this as a flaw or a potential bug. if you change your types after the fact, you should expect issues. Second, the known object shorthand is not the same as var. It is saying "use the type I said to use". Again, if you try to change the type on the left, you should expect issues whether you have this syntax in use or not. 4. & 5. - Yeah, I like these a lot, especially the "not". Oh man, have I been waiting for that one.
Switch statement & pattern matching is more of an FP paradigm feature and unfortunately, it has been neglected in OOP languages for quite some time. It is good to see that C# is incorporating some neat ideas from FP. Let's hope they make var infer Func types as well in the near future.
2.2 When 'newing' an object you no longer need the 2nd reference to the type i.e. Person p = new Person(); becomes Person p = new(); Does not work with object initialization syntax.
In my opinion the inline parameter hints should disappear once you have entered valid parameters. If you need them back click anywhere in the parameters section.
I agree. I'm used to that feature because i'm using resharper at work. This has this feature long ago. I deactivated this hence it needs too much space.
My guess is that this might become an option in the editor at some point. I personally like them on all the time. It allows me to quickly scan my code and see the expectations vs the implementation. If I saw "GetFullName("Tim", "Corey")" then I might think that is ok and I wouldn't click into the method but if I saw "GetFullName(lastName: "Tim", firstName: "Corey")" then it would be quickly obvious that it was incorrect (except for people like me who have two first names). :-)
I believe the reason that you have to use the "and" and "or" words in switch expressions is that the && and || operators are short-circuited and you can't use that in these kinds of expressions, likewise, you can't use the & and | operators since they are binary-and & binary-or which would make your "32 or 212" condition fail. Unlike the switch statement that uses labels for the various values (and basically is a glorified GoTo statement) in a switch expression, all the conditions are evaluated until a match is found.
Hi Tim. Very interested in your Blazor Server: In Depth course, however, you've mentioned a couple of times that there are aload of changes to Blazor. Do alot of these changes apply to the contents within the course? Thanks
The 'new()' syntax is definitely something I'll only be using on variable declarations. That just seems like a recipe for unreadable code to use it for existing variables, even if you can hover over and see the actual type. I definitely agree with you when it comes to the 'is not null' part, hah - I love it.
As an ex VB.NET programmer I laughed when I saw "is not null". That's been in VB for ever and is much more readable...but I guess that's the difference between C# and VB. Perhaps this is Microsoft's way of finally getting rid of VB, just stick it all in C# and call it VBC
Great video. Thanks for sharing this. I'm looking forward to trying these out. However, I really dislike that some of these new features aren't similar enough to the current language features. They would have been much easier to learn and change over to if they kept similar language. For instance, the Switch Expressions. If they'd changed to this, they'd be simpler to translate our understanding to: rec.Summary = switch(rec.TemperatureF) { < 0 => "Well below freezing", >= 0 && < 32 => "Other", else => "Hot" }; In fact, what would be better would be if each of those lines worked exactly like an if statement, which they almost do. And it's a shame you can't use: = new { id=1 }; That seems like a hole that will be filled in the next version.
I prefer the "and" instead of "&&" but I do wish they would bring it back to if statements. I think the "&&" is an unnecessary barrier to entry when learning C#. "and" makes much more sense and is easier to read. As for the else at the end, we are using a (newer) common C# syntax with the underscore (discard). We can use that syntax anywhere in C# where we want to say "I don't care about this variable". For example, in a tuple, you might define it as "var (x, y) = GetTupleValue();" but if you only care about x, you can say "var (x, _) = GetTupleValue();" and the second value will never be assigned. That saves a bit of memory and it keeps us from creating variables we never use.
@@IAmTimCorey I think the problem isn't really '&&' - it's that '&&' and '&' both can be used in if statements, but they have different meanings in the program flow. _&&_ , _||_ , and _!_ are Boolean algebra operators. The _is_ , _and_ , _not_ etc. keywords are used to create a Boolean value from any value, and so have different meanings. The Boolean operators in C# are inherited from C, other languages have different operators, like _And_ , _Or_ and _Not_ in VB. In mathematical notation most commonly AND is ∧, OR is ∨ and NOT is ¬. Also, the _is_ keyword is not entirely interchangeable with ==. (x == null) could have a different result than (x is null) since == can be overloaded. I'm not a mathematician or logician, but I think that the new operators could be viewed as set operators, while the old are Boolean operators. it_is_pleasant = temperature ∈ {n| 18 < n < 30} ∧ it_is_raining ∉ { true } ∧ wind_speed ∈ {n| 0.5 < n < 4} C# 9.0 var it_is_pleasant = temperature is > 18 and < 30 && it_is_raining is not true && wind_speed is > 0.5 and < 4; _&&_ separates the "functions" on temperature, it_is_raining and wind_speed. In this case I prefer 'it_is_raining is not true' to 'it_is_raining is false' or '!it_is_raining'. If the variable was a negative - 'it_is_not_raining', I would just use that, not 'it_is_not_raining is true' or 'it_is_not_raining is not false'. If you're evil you could even write "it_is_raining is not not not !true or true and false"😛 pre C# 9.0: var it_is_pleasant = temperature > 18 && temperature < 30 && !it_is_raining && wind_speed > 0.5 && wind_speed < 4; Note that you must repeat the variable for each part of the expression ( temperature > 18 && temperature < 30 ). Also you could write it like this if you were insane. var it_is_pleasant = temperature > 18 && wind_speed < 4 && !it_is_raining && wind_speed > 0.5 && temperature < 30 ; With Boolean operators replaced with the new keywords. var it_is_pleasant = temperature is > 18 and < 30 and it_is_raining is not true and wind_speed is > 0.5 and < 4; In my opinion it is not more readable, and it gets a lot harder for the compiler.
Units if you need them 😀: temperature is Centigrade, windspeed is meter/second. I used snake case because UA-cam's font is not good for code. EDIT reason: UA-cam needs a preview message function or support Markdown or both. 🙄
I totally agree that it should be possible to use '= new { Id=1 }'. I'd actually go further and say that Person p1 = { FirstName = "Tim", LastName = "Curry" } // 😛 should be possible. No 'new()', not even 'new'. rec.Summary = switch(rec.TemperatureF) ..would be problematic since it'd be hard for the compiler, and it doesn't really look 'nicer'. It should be possible to create an analyzer that can change it to the correct form if you write it like that though. Same goes for 'else' or what I would prefer - 'default' - instead of _ as the catch-all. Hey - maybe 'otherwise' 😀 See my other reply for my thoughts about "&&" in the expressions. TLDR; in an if statement these are equivalent in C#: if( rec.temperatureF is >= 0 and < 32 ) rec.Summary = "Other"; if( rec.temperatureF >= 0 && rec.temperatureF < 32 ) rec.Summary = "Other"; in a switch expression you can write: re.Summary = rec.TemperatureF switch { < 0 => "Well below freezing", < 32 => "other" // pretty darn cold? < 50 => "livable", < 70 => "warm" }; There's no reason to use '>= 0 and < 32' unless you specifically want cases to be caught by a later pattern. A thought I just had is that instead of 'switch' they could use 'is' or something - perhaps 'match'?... Then it would be re.Summary = rec.TemperatureF match { => "..", < 32 => "other", < 50 => "..", _ => ".." }; Not sure if it gains readability though, and having yet another keyword is a lot of work..
Somewhere you arw wrong 20:40 args variable is available in Top Level Calls in Console.Writeline(args) and it can take by default args as string type but it can return int in cmd arguments from synthesised Main method in class
Finally Inline parameter name is a thing in visual studio. I've really missed this feature from Jetbrains products. If we could get current variable values over the variable name when debugging, I would be a very happy man.
56:07 the new switch syntax feels a lot like SQL CASE statements, which I've always liked better than (the old) switch statements. I believe I'll find a lot of utility with this new syntax.
Thanks Tim.... A lot of cool stuff which makes life easier. It doesn't matter whether it is like python or not.... It just makes more flexibility to developer which to use. I really like the init setter, it really makes sense.
pattern matching in switch expression My personal opinion I find this feature very useful. If you write less code: Yes, I think so Is the code more readable: I think so. In the CleanCode world, the switch case function is not good stuff, but I think we can find a good approach here.
Kudos, you Covered quite a bit. Like to point out that likely, the reason you need use and/or/not is because this must work from lambda/linq, which has set the pattern to use words, not symbols, so it can use the operators that link back up directly with the sql convertor for producing a sql query And because it would be confusing to see and/or/not plus the &&/||/! Symbols within the same query, linq, lambda, or other statement. You can use *not* in your logic statements, now, be it an if, ternary if, or other logical statement outside of a LInQ-Query, lambda, etc for those times when using not makes sense: IVehicle vehicle = GetRandomVehicleInstance(); //you can also do *_if(vehicle is not null)_* if(vehicle is null) throw new ArgumentNullException(...); if(vehicle is not Motor Vehicle mv) { //do something, it's likely a bike, skateboard, or similar } else { switch(mv) { case mv is Car c: //... break; //... case Airplane ap: //... break; default: //... break; } } Not the best looking code but that's all 4 variations crammed into 1 example. Also, iirc, *_is not_* works when comparing to other constants, not just used for type pattern and null pattern, but that's another thing altogether
@@IAmTimCorey You're welcome. Love your videos because they do a great job of keeping it simple for the lay or newer programmer while getting smg into the weeds to still benefit more advanced programmers. I have noticed that you don't get hyper focused on the gnitty gritty, semantics, or getting that "perfect code" which often distract or detracts from someone's lesson, but you instead stick to the core lesson, and as such, I like to send peeps to your videos. Keep up the great work!
22:30 Why should your starting point class always be Program.cs? It gets confusing when I have multiple projects in one solution, and each one has a Project.cs. This meant that I have to double check that I'm editing the correct Project.cs file. So I started renaming them to .cs.
Great video as always! Love this channel! I have been working with C# since the version 1.0. Currently, I write not that much code anymore, I but still follow c#/.net developments. I must say, that the last 5 years or so of added features make me worry that some “features” are added “because we can”. Discards, local functions, default interface implementations and now these top level calls and shorthand init? Where is the actual added value? People who are learning c# now will likely to jump on these “new features” because they are “cool”. They do not do much other than making code look more complex and cryptic. Why shorten the code to the state where you need a reference manual on all language versions(which are now 9!)? This just makes its harder to read and waste more time on figuring out what it is going on. My personal preference from 20 years of experience with c# is that the more explicit things are, the less chances someone gets them wrong and create problems for everyone. Maybe I am just old and stupid, but here are my 2 cents ))
I agree with writing explicit code, but there is something to be said for being more concise about it. For instance, saying "PersonModel p = new();" is just as clear as "PersonModel p = new PersonModel();" and yet it reduces the redundancy. So I'm all for things like that. As for discard characters, those allow us to explicitly say "I don't care about this value" instead of being forced to capture it and then never use it. The init in properties changes how properties operate. The closest you could come would be a private set and then setting the value in the constructor, but that's not the same because you still could change it later inside the class. Default implementations in interfaces allow us to "upgrade" interfaces to handle new circumstances instead of creating duplicate interfaces with just a few additional methods. So instead of IEmployee, IEmployeeWithFire, IEmployeeWithFireAndLayoff, we can just have IEmployee and a couple of default implementations for the additional methods. That allows for backwards support while allowing us to move forward. Yes, that can be abused by those who don't understand that, but that's true of most things in development. Yes, adding these new options adds complexity to C#, but it also adds functionality that is needed/valuable. The key is to only use things that you understand. In that way, you can still write C# the same way you did 15 years ago and you will be fine.
@@IAmTimCorey Totally agree with you.I understand the purpose of these additions, but they seem not that significant in terms of added abilities to me. They feel like they are adding more variations to how same things can be achieved. It's not bad at all. It's just seems that compared to, for example: generics, lambdas, dynamic binding, async await, etc.; which made a huge difference in terms of functionality of different c# versions, these are somewhat minor things. 🙂
I just made a similar case above before reading your response. I completely agree. I've been with C# since .NET 1.0 was shipped on CDs and I must say, the language was very structured and slowly has degraded into cryptic unintuitive garble that can no longer be read easily unless you know all the shorthand and background voodoo. Microsoft is aiming to make it into another JavaScript with all the dynamic implicitness and unintuitive syntax. Shame.
That video about the "little things" would be very welcome.... about the "top-level-code" thing... I'm waiting for something of this kind for a long time... it is not the desired result yet (that would be no-class-top-level-functions) but--- bummer... when I used it in a Class Library it failed right away... -> "no top-level-code in class library" what I think would really be useful is "Top Level Classless Functions"... so you could write some "no-class" functions/functionality... and use it in code.. or directly in C# interactive... (so you can code your own script like functionality)
Top level code is for replacing Main, since the namespace, class name, and method name aren't really necessary (or even really valid since you cannot call Main from another method). Class libraries do not have an entrypoint like Main because they cannot be run directly. It would not make sense to enable top-level calls in them. The issue with top-level functions would be that there is no way to call them. With Main, only the compiler is calling it so it does not need a method name or signature. With custom method, they need the signature line and they need to be in a class and namespace to call them correctly. That ceremony is necessary.
@@IAmTimCorey yes,,, that is true... but would not be nice if you declare in your Library public (static) ThisIsAGlobalFunction( int x ){ Console.Write( x ); } and you can use this function anywhere you load this library... even in the C# interactive console (this beeing the main goal)! I invoke my Python experience in my defense... but I could also invoke JS/ES or a lot of other languages... I think this could be 'arranged' with a automatic global/anonymous/partial object (automatically injected by the compiler in the AST when classless functions detected) where this functions would be appended as static members (each library loaded would append here their functions) the compiler... or the Roslyn parser would just have to look in this class for not found invokable members (static functions) Some syntatic sugar... and we could almost have a interactive Python like scripting environent inside Visual Studio...
Great video When you showed the p3 is null, you copied the $”” string but kept the p.Id and did not change to p3.Id ;-) How do you add the option for auto complete when you type public int variable?!
I did not get the point of 'init' - what's the difference to readonly properties (just with get)? They are also initialized within an constructor and are immutable after that. And for value types there are structs, aren't there?
A read-only property can be set in the constructor but not using the curly-brace syntax. While Records act like value types in their operation, they are reference types. So there are subtle differences such as being able to inherit from other records, being able to implement interfaces, passing the reference around as a variable, etc.
@IAmTimCorey I actually prefer the var syntax over the new() syntax. I think that the new() syntax discourages the use of polymorphism and patterns such as Factory.
I don't see the correlation. If you were going to do var p = new Person(); and did Person p = new(); then you weren't using polymorphism. If you are using var, you aren't doing Person p = new BetterPerson(); anyway so BetterPerson p = new(); is just fine. If you are doing var then you aren't using the factory so using new() won't be any different.
This name hint idea probably came from JetBrains Rider. As I'm a Linux user, it is the only IDE at head of Visual Studio that I can use. The concurrency it's a gem. By the way, Rider has non community like download available.
Tim, could you please clarify something tangential for me. Will MAUI make Blazor redundant? Seems like they are both trying to tackle the same domain: unifying web, mobile and desktop development. How will the two projects look like in your view?
No, MAUI might make WinForms and WPF less used going forward but it will not affect ASP.NET Core project types (like Blazor) negatively. The unification comes on the desktop and mobile side. We already have unification on the web side.
1:04:24 That's very important feature tbh. The only way to do null checking properly in all cases (think about poorly implemented overloaded != == operators) is through Reference.Equals(x,null) which is ugly but translates to (x is null) . It always bothered me why you have to do !(x is null) or (x is null) ==false when (x is not null) is the most logical and natural syntax.
I know you have not historically been a fan of EF. However, I was wondering if you feel the improvements to EF Core 5 (devblogs.microsoft.com/dotnet/announcing-the-release-of-ef-core-5-0/) merit reconsidering going down the path of using EF with Databases?
3.1 New relational pattern usable with a switch expression. Great for creating categorization of data based on value. 3.2 New relational pattern using logic with 'and/or' usable with a switch expression. Great for creating categorization of data based on value.
Regarding new() there's so many caveats, you should just use var when assigning on the same line or if you're going to set a value later, of course just specify the type. Telling new developers they can do something with 50 caveats is going to make their code bad.
Options are good. I think the new() syntax will be a good option for a lot of situations. The readability is better than var, in my opinion, so I've been using it more and more in my own development.
Yes it is production-read. Microsoft has been using it in production for almost a year, so it is also battle-tested. Yes, you will see a lot of value upgrading your Blazor WebAssembly app to .NET 5.0 (it will be faster and smaller).
I use the wireless Logitech K800 keyboard ( amzn.to/3kTbi6A ) and love it. I've used this particular one for years and it has held up great, even with all of my daily typing.
Great Videos. Would be great if you can keep them short and to the point. You jump from 1 point to another to another before coming to main topic. hard to keep patience and focus for that long :)
I understand, but context is important. Otherwise, you are "learning" new things in a vacuum. You need to know how they will interact with the rest of your code.
p3 = new() - newer will goes clear in PR review in some WebUI (GitLab, AzureDevOps, ets) so agree -> Define types clear to read code (You read code more than write one)
I think the naming by Microsoft could have been better for those if/else statements to differentiate it with the actual switch statement. A name like arrowCond or something would be better since it's not a known switch behavior in fact.
Well, this is like the using statement and the using directive. We have switch statements and switch expressions (which is what we showed off here). They are different, but very similar in how they act.
Interesting. Is not null is vb syntax. Relational and logical pattern matching is what a vb case statement has been using for 25 years. It looks like they are just copying vb features over. Finally. Let us hope other vb features (like not having to constantly convert data types even when it's obvious) also get carried over one day as well. Best of both languages. Seems to be taking them awhile but we're getting there.
init is missing a crucial feature imo. I wish I could mark it as being "not optional" in a way. So that if you create a new object using the curlies, then you HAVE to set it.
will you be able to make videos about SQL in near future? like SQL transaction, optimization or common SQL mistakes to avoid? I know there are a lot of things to cover especially when .net 5 is released. but I hope you make some videos about SQL server or SQL in general in the near future.
Your project templates will for a while until Microsoft updates them (except for web projects, which already have the dropdown selector for the version). Just go into the properties of the template and change the version.
As I demoed in the video, you can only have one file that has top-level code in it. If you reference other assemblies, they aren't executing independently, they are just libraries that you call. In that case, they would not be able to have any top-level code because they aren't starting on their own. Only the UI can have top level code.
Tried to use Top Level Calls in an Web Api project. Removed Program Class and Main() from Program.cs. Project built fine, but EF add-migration command failed :-(
I would avoid doing this for API projects (or web in general). It can probably be done but I don't think the value outweighs the problems you will encounter.
@@IAmTimCorey Thanks for the reply! I was just playing with the new features. I agree with you. There is no point reducing a few lines of code from a web or api project. After a web or api project is created and built successfully, nobody ever looks inside Program.cs.
Anyone else having problems with getting C# 9? I have Visual Studio 16.8.2 already and installed .NET 5, but Visual Studio tells me I need to change to 9.0 and init is marked red. Changed the target framework in properties as well and restarted PC, did not help.
Inline setters My personal opinion This feature is really a great thing. Does it make the code more readable? I would say yes Are we writing less code? No not decisive for this feature. I would say great.
21:01 For the top level code you can use args as if they exited in the normal Main method. Just type args
That's awesome! I missed that. Thanks for pointing it out.
Yup, that's because Roslyn just wraps the top level code in a new static main method behind the scenes. The framework does not support top level statements, thus the C# parser modifies it to match the framework specifications (similar to linq queries which are converted to linq expressions since the framework doesn't know about them).
0:00 - Intro
0:55 - Getting started: Visual Studio version
1:46 - 1. Top Level Calls ...
4:23 - /* Note: Inline parameter name (VS feature) *
/
8:43 - /* Note: .Net 5 vs .Net core *
/
11:07 - 1. ... Top Level Calls
18:55 - Why top level calls?
23:20 - 2. Initial setter
s
32:28 - 3. Known object type shorthand instantiation
40:36 - Recap and creating new demo Blazor app
42:30 - Demo Blazor app "fetch data"
44:17 - Improving Demo Blazor app "fetch data" code
47:45 - 4. Relational pattern matching in switch expression
54:18 - 5. Logical pattern matching in switch expression
1:04:24 - 6. "is not" pattern
1:08:30 - Recap
1:08:58 - Summary and concluding remarks;
You did forgot to add timestamps tho. :D
Cunning way to get me watch your videos out of order specified in "learning path".
thank you, as speaking pace here is very slow
Thanks!
@@iXmerof try
shift + .
;)
Wow there is a Shift Tab available all this time and a complete list for undos and redos. Thank you for sharing these small things.
You're very welcome! They can really help
I am watching these videos while walking. Thank you very much! You are doing a great job
You are welcome.
Great stuff, man. Really learned a lot watching your videos.
Just want to point out that the command line arguments still work in top-level programs. You can just use the variable `args` as you generally would in the more verbose setup and it works.
Thanks! I didn't realize that.
Collections is where I think the shorthand instantiation shines.
var people = new PersonModel[] {
new(1, "Tim", "Corey"),
new(2, "Sue", "Storm")
}
Yep, that's another great use.
Ahh yes. Really makes it a lot more readable. And then its also possible to make VS studio show what the values being set in the constructor are called if you enable that feature.
That is great
No, as it is nothing new. Anonymous classes, Tuples or initializer list have been possible already. Btw. in OOP this case is super rare - except creating data based unit tests perhaps, but there you'll use edge corner data sets, and do not test with semantical equivalent data.
@@arneschneidermann8059 but this is not based on anonymous classes or tuples. Making a test dateset for unit testing should not really be a rare thing either. An anonymous class can be useful, same with tuples, but both should be avoided in most cases.
Top level calls is such an artificial change, probably introduced just to "keep up the appearance" against dynamic languages like Python. It doesn't even look in line with general best practices
"is not" is now interchangeable with "!=" when comparing to constant values. Not only "null".
Works:
int n1 = 4;
if (n1 is not 5)
{
System.Console.WriteLine("n1 is not 5");
}
Does not work:
int n1 = 4;
int n2 = 5;
if (n1 is not n2)
{
System.Console.WriteLine("n1 is not n2");
}
It would probably also work when checking polymorphic class objects. Something like:-
if(myShape is not Square){}
@@babri1402 you can already do: `if (myShape is Square mySquare)`, which creates a new variable "mySquare" which is a casted version of myShape using the Square class (if it's part of the hierarchy).
Those switch expressions... very sweet!
Also, initial setters. Very nice!
I hope I'll get to use all of this some day... :)
You will! Hang in there
I'm sure we all will be used to that in no time...at least i wanted the logical patterns and the init setter long ago. The switch expression might be a bit tricky to get that in mind when it's time to use it :) I'm sure that Resharper will give me a hint like allways^^
I can't tell you how many times I tried to type out "is not null" before, "is null" was already there so it just made sense to me that I should be able to throw a 'not' in there. Switch expressions will make my life a lot simpler I predict as well.
Yeah, it is a big quality of life upgrade for me.
Thanks for this video Tim, I like your manner of explanation. Just want to share my personal opinion about these features.
1. Top level calls: now I see less code which i never wrote))) it was always autogenerated by VS
2. Inline parameter names: it was in resharper long time ago and it is useful for me
3. Initial setter: my personal, it is not useful for me, due to you have to have reasons to make immutable property that's why private setter is better for me
4. Short hand instantiation: interesting one, but we already have "var" for shorten variable declaration
5. Switch expression: Best feature in this release!
6. Logical "is not" in conditions looks more intuitive, but in same time "!=" short and easy.
Have a good day folks!
Thanks for sharing.
Good video Tim. I really hate where C# has gone in the past several years. Everything I liked about the language is being offset by dynamic features" that degrade it. If I want to code in JavaScript, I'll code in JavaScript. C# shouldn't try to be something it isn't.
Life, and programming, is about change. The market is changing and Microsoft is meeting the demands of that marketplace. The good news is that you don't have to use the newer features of the language. You can stick to what you like without a problem.
Thank you for sharing. One comment on using the Top Level Calls. I have been teaching C# and one thing the students found very difficult is to know where to insert code. This whole stuff with namespaces, classes, methods has a role, it is meant to create abstraction levels and is therefore very useful. In teaching C# console applications with all this boilerplate code can be very useful just to demonstrate how it works. Understanding a bit of how it works can be very helpful if you try to do more complicated things. And keep in mind, the project template will create this boilerplate code for you. So it just for readability,
Thanks for sharing
Just a little tip: Disable Resharper if you have it before you start following along with the video. On my machine, this did not go well. Afterwards, you can re-enable it.
Thanks for the info!
I really appreciate you coving all of this. I normally dont listen/read to too much on new features except stuff I am interested in. You successfully lured me in hook and sinker...lol
I really like the new features in cSharp 9. The only problem I see is if a developer doesnt know the new stuff and they look at your code. They will be like WTH... how does that even work?
True, when folks jump in on the advanced topics, they can get lost. I try to point them back to my full teaching playlists where they can learn and build up to the level that this all makes sense. Please help get the word out on where to start - ua-cam.com/video/LUv20QxXjfw/v-deo.html
Sir Excellent take on new features... Sir i owe you soo much... Prayers for your good health..
This video is gold for FREE...
So nice of you
Professionally I've been away from C# for over a year, so this was really interesting to see. Some really useful features I'll be sure to use in my personal projects.
I am glad it was helpful.
Great stuff. Really appreciate your work!
I have been meaning to actually play around with the new features for a while now, this was a great first look. Can't wait for the video on records.
Glad I could help!
So, I'm going to type my thoughts as I watch:
1. Top Level Calls
I understand the reasoning, but I'm to a big fan of this one. Considering that VS already does all the ceremony for you, its easier to just write inside main than to delete all and write top-level. Also, I don't think it makes it easier to read, I think it makes it harder. Reason being that you use that same namespace->class->method structure in basically every file, why would your Program.cs be any different? Its breaking the pattern and that makes it confusing. Also, most C# developers will soon in their careers get used to the extra ceremony to the point of not even noticing anymore.
2. Initial Setters
That's a cool feature, but I bet i'm not gonna remember to use it. Similar to things like internal, where I know it exists, I know what its use case, but I rarely use it and often find out that the method I thought it could be internal, actually has to be public for me to include it in the interface.
3. Known Object Type Shorthand Instantiation
Not a fan of this either. I likely won't use it for the same reason I don't like to use var. First of, with intelllisense, typing the class name for a second time can be done in 2 or 3 keystrokes, no matter how big the name is. Secondly, var can cause a lot of problems. Lets say you do var p = new PersonModel(), instead of PersonModel you could have anything else in there and var would accept it. By having to type it twice, you are twice as likely to notice in case you are instantiating the wrong class. That can become even more dangerous if, in the future, you decide to change that line to var p = MyFunction(). If your function doesn't return the correct type, var will take it anyway and may only notice when something goes wrong at runtime. Similar reasons apply to this shorthand, but without the benefits of var, so I'm likely not going to use it.
4. and 5. Relational and Logical Pattern Matching in Switch Expression
I absolutely love that. I've always thought that switch statements are a underused feature of many programming languages and one of the main reasons for it is its limitations. Being able to do switch expressions with continuous and infinitely varied values with a notation that is even easier then regular switch statements is a very good feature that allows us to make much more readable code.
1. I covered top-level calls in another comment, but the gist is that the namespace, class, and method names don't apply to the Main method in the same way they do anywhere else in C#. You can't call Main (you would cause an infinite loop) so we have something that is in Intellisense but we have to know not to call it. That's where I see it being a big deal. I can easily see the templates being updated to use this top-level syntax going forward.
2. I can see forgetting something if you don't use it all the time. I don't think this is a huge feature, but it is a big deal in specific situations.
3. Couple of things here. First, var does not allow a type change unless you physically change the type assigned to it. I don't see this as a flaw or a potential bug. if you change your types after the fact, you should expect issues. Second, the known object shorthand is not the same as var. It is saying "use the type I said to use". Again, if you try to change the type on the left, you should expect issues whether you have this syntax in use or not.
4. & 5. - Yeah, I like these a lot, especially the "not". Oh man, have I been waiting for that one.
Switch statement & pattern matching is more of an FP paradigm feature and unfortunately, it has been neglected in OOP languages for quite some time.
It is good to see that C# is incorporating some neat ideas from FP. Let's hope they make var infer Func types as well in the near future.
I’m enjoying .NET 5 so much! I’ve been waiting all year for it 😊
Same here!
2.2 When 'newing' an object you no longer need the 2nd reference to the type i.e.
Person p = new Person();
becomes
Person p = new();
Does not work with object initialization syntax.
Thanks for sharing
What do you mean? He did so at 36:45 or did i misunterstood?
In my opinion the inline parameter hints should disappear once you have entered valid parameters. If you need them back click anywhere in the parameters section.
I agree. I'm used to that feature because i'm using resharper at work. This has this feature long ago. I deactivated this hence it needs too much space.
My guess is that this might become an option in the editor at some point. I personally like them on all the time. It allows me to quickly scan my code and see the expectations vs the implementation. If I saw "GetFullName("Tim", "Corey")" then I might think that is ok and I wouldn't click into the method but if I saw "GetFullName(lastName: "Tim", firstName: "Corey")" then it would be quickly obvious that it was incorrect (except for people like me who have two first names). :-)
I believe the reason that you have to use the "and" and "or" words in switch expressions is that the && and || operators are short-circuited and you can't use that in these kinds of expressions, likewise, you can't use the & and | operators since they are binary-and & binary-or which would make your "32 or 212" condition fail. Unlike the switch statement that uses labels for the various values (and basically is a glorified GoTo statement) in a switch expression, all the conditions are evaluated until a match is found.
I really like how I can finally do List = new();. Instead of List = new List();
Me too.
Hi Tim. Very interested in your Blazor Server: In Depth course, however, you've mentioned a couple of times that there are aload of changes to Blazor. Do alot of these changes apply to the contents within the course? Thanks
hats off to you, sir! Yet another time.
Thanks again!
Nice video. Seems like C# is becoming more concise, like a traditional functional programming language.
Thanks!
The 'new()' syntax is definitely something I'll only be using on variable declarations. That just seems like a recipe for unreadable code to use it for existing variables, even if you can hover over and see the actual type.
I definitely agree with you when it comes to the 'is not null' part, hah - I love it.
Yep, that's how I feel.
As an ex VB.NET programmer I laughed when I saw "is not null". That's been in VB for ever and is much more readable...but I guess that's the difference between C# and VB. Perhaps this is Microsoft's way of finally getting rid of VB, just stick it all in C# and call it VBC
VBC#
You are awesome!
I like your voice, I like your accent, I like the way you explain things
I feel like my friend explains something to me
Thank you
You are welcome.
Great video. Thanks for sharing this. I'm looking forward to trying these out.
However, I really dislike that some of these new features aren't similar enough to the current language features. They would have been much easier to learn and change over to if they kept similar language. For instance, the Switch Expressions. If they'd changed to this, they'd be simpler to translate our understanding to:
rec.Summary = switch(rec.TemperatureF)
{
< 0 => "Well below freezing",
>= 0 && < 32 => "Other",
else => "Hot"
};
In fact, what would be better would be if each of those lines worked exactly like an if statement, which they almost do.
And it's a shame you can't use: = new { id=1 };
That seems like a hole that will be filled in the next version.
I think this is a good point.
I prefer the "and" instead of "&&" but I do wish they would bring it back to if statements. I think the "&&" is an unnecessary barrier to entry when learning C#. "and" makes much more sense and is easier to read. As for the else at the end, we are using a (newer) common C# syntax with the underscore (discard). We can use that syntax anywhere in C# where we want to say "I don't care about this variable". For example, in a tuple, you might define it as "var (x, y) = GetTupleValue();" but if you only care about x, you can say "var (x, _) = GetTupleValue();" and the second value will never be assigned. That saves a bit of memory and it keeps us from creating variables we never use.
@@IAmTimCorey I think the problem isn't really '&&' - it's that '&&' and '&' both can be used in if statements, but they have different meanings in the program flow.
_&&_ , _||_ , and _!_ are Boolean algebra operators. The _is_ , _and_ , _not_ etc. keywords are used to create a Boolean value from any value, and so have different meanings.
The Boolean operators in C# are inherited from C, other languages have different operators, like _And_ , _Or_ and _Not_ in VB. In mathematical notation most commonly AND is ∧, OR is ∨ and NOT is ¬.
Also, the _is_ keyword is not entirely interchangeable with ==. (x == null) could have a different result than (x is null) since == can be overloaded.
I'm not a mathematician or logician, but I think that the new operators could be viewed as set operators, while the old are Boolean operators.
it_is_pleasant = temperature ∈ {n| 18 < n < 30} ∧ it_is_raining ∉ { true } ∧ wind_speed ∈ {n| 0.5 < n < 4}
C# 9.0
var it_is_pleasant = temperature is > 18 and < 30 && it_is_raining is not true && wind_speed is > 0.5 and < 4;
_&&_ separates the "functions" on temperature, it_is_raining and wind_speed.
In this case I prefer 'it_is_raining is not true' to
'it_is_raining is false'
or
'!it_is_raining'.
If the variable was a negative - 'it_is_not_raining', I would just use that, not
'it_is_not_raining is true' or
'it_is_not_raining is not false'.
If you're evil you could even write "it_is_raining is not not not !true or true and false"😛
pre C# 9.0:
var it_is_pleasant = temperature > 18 && temperature < 30 && !it_is_raining && wind_speed > 0.5 && wind_speed < 4;
Note that you must repeat the variable for each part of the expression ( temperature > 18 && temperature < 30 ).
Also you could write it like this if you were insane.
var it_is_pleasant = temperature > 18 && wind_speed < 4 && !it_is_raining && wind_speed > 0.5 && temperature < 30 ;
With Boolean operators replaced with the new keywords.
var it_is_pleasant = temperature is > 18 and < 30 and it_is_raining is not true and wind_speed is > 0.5 and < 4;
In my opinion it is not more readable, and it gets a lot harder for the compiler.
Units if you need them 😀: temperature is Centigrade, windspeed is meter/second.
I used snake case because UA-cam's font is not good for code.
EDIT reason: UA-cam needs a preview message function or support Markdown or both. 🙄
I totally agree that it should be possible to use '= new { Id=1 }'.
I'd actually go further and say that
Person p1 = { FirstName = "Tim", LastName = "Curry" } // 😛
should be possible. No 'new()', not even 'new'.
rec.Summary = switch(rec.TemperatureF)
..would be problematic since it'd be hard for the compiler, and it doesn't really look 'nicer'. It should be possible to create an analyzer that can change it to the correct form if you write it like that though. Same goes for 'else' or what I would prefer - 'default' - instead of _ as the catch-all. Hey - maybe 'otherwise' 😀
See my other reply for my thoughts about "&&" in the expressions.
TLDR;
in an if statement these are equivalent in C#:
if( rec.temperatureF is >= 0 and < 32 ) rec.Summary = "Other";
if( rec.temperatureF >= 0 && rec.temperatureF < 32 ) rec.Summary = "Other";
in a switch expression you can write:
re.Summary = rec.TemperatureF switch
{
< 0 => "Well below freezing",
< 32 => "other" // pretty darn cold?
< 50 => "livable",
< 70 => "warm"
};
There's no reason to use '>= 0 and < 32' unless you specifically want cases to be caught by a later pattern.
A thought I just had is that instead of 'switch' they could use 'is' or something - perhaps 'match'?... Then it would be
re.Summary = rec.TemperatureF match { => "..", < 32 => "other", < 50 => "..", _ => ".." };
Not sure if it gains readability though, and having yet another keyword is a lot of work..
What an amazing video for a c# noob like me. Thank you, the best video i have ever seen.
You are welcome.
Somewhere you arw wrong 20:40
args variable is available in Top Level Calls in Console.Writeline(args) and it can take by default args as string type but it can return int in cmd arguments from synthesised Main method in class
Yep, I missed that. I point it out in the next video.
Thanks Tim. Really appreciate your work. I am looking for some content on row level security and data masking solutions. Thanks in advance
Happy to help!
"Just because they are new, it doesn't mean they're valuable" - well said @IAmTimCorey
Thanks.
Finally Inline parameter name is a thing in visual studio. I've really missed this feature from Jetbrains products. If we could get current variable values over the variable name when debugging, I would be a very happy man.
There are cool free VS Plugins that can do this
@@neralem Which do you suggest?
56:07 the new switch syntax feels a lot like SQL CASE statements, which I've always liked better than (the old) switch statements. I believe I'll find a lot of utility with this new syntax.
Yep, the switch expression is very similar to what we do in SQL.
Had to laugh. Favorite c# enhancement is vb.net syntax. Is Not Nothing. :)
Thanks Tim.... A lot of cool stuff which makes life easier. It doesn't matter whether it is like python or not.... It just makes more flexibility to developer which to use. I really like the init setter, it really makes sense.
Very true!
pattern matching in switch expression
My personal opinion
I find this feature very useful.
If you write less code: Yes, I think so
Is the code more readable: I think so.
In the CleanCode world, the switch case function
is not good
stuff, but I think we can find a good approach here.
Thanks for sharing
Awesome content. Nice to see "is not null" getting picked up from SQL Server.
Thanks
Have you tested the init setter with Dapper to make sure they work well together?
@11:10, I was sad you didn't use CTRL K + CTRL D. Or even better, format on save.
I forget shortcuts that I do not use frequently.
Kudos, you Covered quite a bit.
Like to point out that likely, the reason you need use and/or/not is because this must work from lambda/linq, which has set the pattern to use words, not symbols, so it can use the operators that link back up directly with the sql convertor for producing a sql query And because it would be confusing to see and/or/not plus the &&/||/! Symbols within the same query, linq, lambda, or other statement.
You can use *not* in your logic statements, now, be it an if, ternary if, or other logical statement outside of a LInQ-Query, lambda, etc for those times when using not makes sense:
IVehicle vehicle = GetRandomVehicleInstance();
//you can also do *_if(vehicle is not null)_*
if(vehicle is null)
throw new ArgumentNullException(...);
if(vehicle is not Motor Vehicle mv)
{
//do something, it's likely a bike, skateboard, or similar
}
else
{
switch(mv)
{
case mv is Car c:
//...
break;
//...
case Airplane ap:
//...
break;
default:
//...
break;
}
}
Not the best looking code but that's all 4 variations crammed into 1 example.
Also, iirc, *_is not_* works when comparing to other constants, not just used for type pattern and null pattern, but that's another thing altogether
Thanks for sharing.
@@IAmTimCorey You're welcome. Love your videos because they do a great job of keeping it simple for the lay or newer programmer while getting smg into the weeds to still benefit more advanced programmers.
I have noticed that you don't get hyper focused on the gnitty gritty, semantics, or getting that "perfect code" which often distract or detracts from someone's lesson, but you instead stick to the core lesson, and as such, I like to send peeps to your videos. Keep up the great work!
22:30 Why should your starting point class always be Program.cs? It gets confusing when I have multiple projects in one solution, and each one has a Project.cs. This meant that I have to double check that I'm editing the correct Project.cs file. So I started renaming them to .cs.
The new shorthand for object instantiation is great.
I agree.
12:15 A method inside of another method? Mind = Blown.
Pretty cool, huh?
Great video as always! Love this channel!
I have been working with C# since the version 1.0. Currently, I write not that much code anymore, I but still follow c#/.net developments. I must say, that the last 5 years or so of added features make me worry that some “features” are added “because we can”. Discards, local functions, default interface implementations and now these top level calls and shorthand init? Where is the actual added value? People who are learning c# now will likely to jump on these “new features” because they are “cool”. They do not do much other than making code look more complex and cryptic. Why shorten the code to the state where you need a reference manual on all language versions(which are now 9!)? This just makes its harder to read and waste more time on figuring out what it is going on. My personal preference from 20 years of experience with c# is that the more explicit things are, the less chances someone gets them wrong and create problems for everyone.
Maybe I am just old and stupid, but here are my 2 cents ))
I agree with writing explicit code, but there is something to be said for being more concise about it. For instance, saying "PersonModel p = new();" is just as clear as "PersonModel p = new PersonModel();" and yet it reduces the redundancy. So I'm all for things like that. As for discard characters, those allow us to explicitly say "I don't care about this value" instead of being forced to capture it and then never use it. The init in properties changes how properties operate. The closest you could come would be a private set and then setting the value in the constructor, but that's not the same because you still could change it later inside the class. Default implementations in interfaces allow us to "upgrade" interfaces to handle new circumstances instead of creating duplicate interfaces with just a few additional methods. So instead of IEmployee, IEmployeeWithFire, IEmployeeWithFireAndLayoff, we can just have IEmployee and a couple of default implementations for the additional methods. That allows for backwards support while allowing us to move forward. Yes, that can be abused by those who don't understand that, but that's true of most things in development.
Yes, adding these new options adds complexity to C#, but it also adds functionality that is needed/valuable. The key is to only use things that you understand. In that way, you can still write C# the same way you did 15 years ago and you will be fine.
@@IAmTimCorey Totally agree with you.I understand the purpose of these additions, but they seem not that significant in terms of added abilities to me. They feel like they are adding more variations to how same things can be achieved. It's not bad at all. It's just seems that compared to, for example: generics, lambdas, dynamic binding, async await, etc.; which made a huge difference in terms of functionality of different c# versions, these are somewhat minor things. 🙂
I just made a similar case above before reading your response. I completely agree. I've been with C# since .NET 1.0 was shipped on CDs and I must say, the language was very structured and slowly has degraded into cryptic unintuitive garble that can no longer be read easily unless you know all the shorthand and background voodoo. Microsoft is aiming to make it into another JavaScript with all the dynamic implicitness and unintuitive syntax. Shame.
That video about the "little things" would be very welcome....
about the "top-level-code" thing...
I'm waiting for something of this kind for a long time...
it is not the desired result yet (that would be no-class-top-level-functions)
but--- bummer... when I used it in a Class Library it failed right away... -> "no top-level-code in class library"
what I think would really be useful is "Top Level Classless Functions"...
so you could write some "no-class" functions/functionality...
and use it in code.. or directly in C# interactive...
(so you can code your own script like functionality)
Top level code is for replacing Main, since the namespace, class name, and method name aren't really necessary (or even really valid since you cannot call Main from another method). Class libraries do not have an entrypoint like Main because they cannot be run directly. It would not make sense to enable top-level calls in them. The issue with top-level functions would be that there is no way to call them. With Main, only the compiler is calling it so it does not need a method name or signature. With custom method, they need the signature line and they need to be in a class and namespace to call them correctly. That ceremony is necessary.
@@IAmTimCorey yes,,, that is true...
but would not be nice if you declare in your Library
public (static) ThisIsAGlobalFunction( int x ){ Console.Write( x ); }
and you can use this function anywhere you load this library...
even in the C# interactive console (this beeing the main goal)!
I invoke my Python experience in my defense...
but I could also invoke JS/ES or a lot of other languages...
I think this could be 'arranged' with a automatic global/anonymous/partial object
(automatically injected by the compiler in the AST when classless functions detected)
where this functions would be appended as static members
(each library loaded would append here their functions)
the compiler... or the Roslyn parser would just have to look
in this class for not found invokable members (static functions)
Some syntatic sugar... and we could almost have a interactive Python like scripting environent
inside Visual Studio...
Great video
When you showed the p3 is null, you copied the $”” string but kept the p.Id and did not change to p3.Id ;-)
How do you add the option for auto complete when you type public int variable?!
I think top level c# code will help begginers, because they don't have to face OOP concepts right away
Possibly
Updating the ternary operator to the new switch format would be a godsend!
👍
is the new SWITCH has a performance advantage over IF, or it's just a compact version of the old SWITCH?
Late reply, but it's just more readable, it gets compiled to the same thing.
I did not get the point of 'init' - what's the difference to readonly properties (just with get)? They are also initialized within an constructor and are immutable after that. And for value types there are structs, aren't there?
A read-only property can be set in the constructor but not using the curly-brace syntax.
While Records act like value types in their operation, they are reference types. So there are subtle differences such as being able to inherit from other records, being able to implement interfaces, passing the reference around as a variable, etc.
Great video dude !
Thank you for the encouragement
Thank you TIM. Another masterpiece !!
Thanks again!
@IAmTimCorey I actually prefer the var syntax over the new() syntax. I think that the new() syntax discourages the use of polymorphism and patterns such as Factory.
I don't see the correlation. If you were going to do var p = new Person(); and did Person p = new(); then you weren't using polymorphism. If you are using var, you aren't doing Person p = new BetterPerson(); anyway so BetterPerson p = new(); is just fine. If you are doing var then you aren't using the factory so using new() won't be any different.
Those little value hints are so neat.
Glad they help
Finally, I've had those in Rider forever and I always missed it in VS... :D
This name hint idea probably came from JetBrains Rider. As I'm a Linux user, it is the only IDE at head of Visual Studio that I can use. The concurrency it's a gem. By the way, Rider has non community like download available.
Thanks for sharing
Hey, I'd love see some incarnation of Visual Studio on Linux. Maybe someday!
Tim, could you please clarify something tangential for me. Will MAUI make Blazor redundant? Seems like they are both trying to tackle the same domain: unifying web, mobile and desktop development. How will the two projects look like in your view?
No, MAUI might make WinForms and WPF less used going forward but it will not affect ASP.NET Core project types (like Blazor) negatively. The unification comes on the desktop and mobile side. We already have unification on the web side.
@@IAmTimCorey Thank you! Both you are your channel are great! Big fan of your work, which has taught me a tremendous amount :)
Hi Tim, can we use "xor" (Exclusive OR Operator) as what we do in VB in the "switch" expression?
I'm not sure. I haven't tried it.
@@IAmTimCorey no worries, I will try it at my end.
Thank you, I love your videos, so informative ^^
Glad you like them!
Really thx for the video, I always learn alot from them. Great Work. Can you explain the new Task Dialog in Windows Forms?
Added to the list.
1:04:24 That's very important feature tbh. The only way to do null checking properly in all cases (think about poorly implemented overloaded != == operators) is through Reference.Equals(x,null) which is ugly but translates to (x is null) . It always bothered me why you have to do !(x is null) or (x is null) ==false when (x is not null) is the most logical and natural syntax.
If only they would ask us ...
@@IAmTimCorey Well i just found out that since C# 8.0 you can write (x is {}) which means x is not null. Looks weird but works.
I know you have not historically been a fan of EF. However, I was wondering if you feel the improvements to EF Core 5 (devblogs.microsoft.com/dotnet/announcing-the-release-of-ef-core-5-0/) merit reconsidering going down the path of using EF with Databases?
3.1 New relational pattern usable with a switch expression. Great for creating categorization of data based on value.
3.2 New relational pattern using logic with 'and/or' usable with a switch expression. Great for creating categorization of data based on value.
Yep.
Thanks you for this video.
My pleasure
Inline parameter hints.
VS: "look it's so new, I'm so innovative"
Rider: "Am I a joke to you?"
R#: ¯\_(ツ)_/¯
Regarding new() there's so many caveats, you should just use var when assigning on the same line or if you're going to set a value later, of course just specify the type. Telling new developers they can do something with 50 caveats is going to make their code bad.
Options are good. I think the new() syntax will be a good option for a lot of situations. The readability is better than var, in my opinion, so I've been using it more and more in my own development.
@@IAmTimCorey Everyone has their own style, but you have the experience to know when it's ok to use, new developers don't.
is .net 5.0 is production ready? Should I migrate my under development Blazor PWA to .net 5.0?
Yes it is production-read. Microsoft has been using it in production for almost a year, so it is also battle-tested. Yes, you will see a lot of value upgrading your Blazor WebAssembly app to .NET 5.0 (it will be faster and smaller).
@@IAmTimCorey thanks for your guidance mate
What type of keyboard do you use? That sounds great. My keyboard always makes my hands hurt.
I use the wireless Logitech K800 keyboard ( amzn.to/3kTbi6A ) and love it. I've used this particular one for years and it has held up great, even with all of my daily typing.
@@IAmTimCorey Many thanks
i have Update visual studio but my version after updated is v16.8.2? Why ?
Because they put out another patch for issues that were discovered.
Great Videos. Would be great if you can keep them short and to the point. You jump from 1 point to another to another before coming to main topic. hard to keep patience and focus for that long :)
I understand, but context is important. Otherwise, you are "learning" new things in a vacuum. You need to know how they will interact with the rest of your code.
p3 = new() - newer will goes clear in PR review in some WebUI (GitLab, AzureDevOps, ets) so agree -> Define types clear to read code (You read code more than write one)
Thanks!
I think the naming by Microsoft could have been better for those if/else statements to differentiate it with the actual switch statement. A name like arrowCond or something would be better since it's not a known switch behavior in fact.
Well, this is like the using statement and the using directive. We have switch statements and switch expressions (which is what we showed off here). They are different, but very similar in how they act.
Did you need to make the first Add method static when you converted the file to a top level call file?
No because it is still a local method, not a public method.
thanks a lot please could you create a video about reporting in the project
Thanks for sharing the suggestion, I added it to the list.
Interesting. Is not null is vb syntax. Relational and logical pattern matching is what a vb case statement has been using for 25 years. It looks like they are just copying vb features over. Finally. Let us hope other vb features (like not having to constantly convert data types even when it's obvious) also get carried over one day as well. Best of both languages. Seems to be taking them awhile but we're getting there.
Thanks for sharing
Hi Tim, So you're saying all these arent production-ready until .Net 6?
No, they are production-ready now.
init is missing a crucial feature imo. I wish I could mark it as being "not optional" in a way. So that if you create a new object using the curlies, then you HAVE to set it.
You can set up the init to be either the value passed in or throw an exception. It isn't exactly what you are looking for but it is closer.
will you be able to make videos about SQL in near future? like SQL transaction, optimization or common SQL mistakes to avoid? I know there are a lot of things to cover especially when .net 5 is released. but I hope you make some videos about SQL server or SQL in general in the near future.
It is on the list but I have lots of high priority stuff ahead of it. Can't promise if or when it will get addressed.
In your last exempel I use: p2 is PersonModel, if p2 is null our if-statement will be false.
p2 is not null so asking if p2 is null will result in false.
@@IAmTimCorey I meant:
p2 is not null = p2 is PersonModel.
Sry for last comment :)
many thanks.
You are welcome.
Hi Tim, Thank you for your videos. Could you make a video machine Learning Crash Course With ML.NET?
Thank you in advance.
I appreciate the suggestion and added it to my list.
@@IAmTimCorey Thank you for your time and consideration.
Well explained
Thanks
My .Net Core keeps Targeting "netcoreapp3.1" and keeps using C# 8.0 I have tried a full reinstall of everything, please help.
Your project templates will for a while until Microsoft updates them (except for web projects, which already have the dropdown selector for the version). Just go into the properties of the template and change the version.
@@IAmTimCorey Thanks my man I was confused about it, always love your videos!
Interesting Video, Thanks for the tips.
No problem!
great content
Thanks!
What if you have multiple references to assemblies that have top level code? Which one will run?
As I demoed in the video, you can only have one file that has top-level code in it. If you reference other assemblies, they aren't executing independently, they are just libraries that you call. In that case, they would not be able to have any top-level code because they aren't starting on their own. Only the UI can have top level code.
@@IAmTimCorey Thanks! And I'm sorry that I was to lazy to check it myself.
Thanks
Thanks a lot for sharing..
My pleasure
2. Init setters. Can only set these properties when the object is created.
Correct.
Thanks man, good video.
Glad you liked it!
I notice the words 'Cloud Explorer' on the left there. Correct me if I'm wrong, but that's an airplane right?
That's the way to work with Azure in Visual Studio. Not sure about it being an airplane, though.
You did it again. Great stuff. And I appreciate the fact that you speak clearly and carefully, because i'm learning english yet. Thanks!
Gracias!
Thanks! 😃
Thanks for the great content
My pleasure!
Having With End With would be nice, like VB.Net
Yeah, that is a nice feature.
Tried to use Top Level Calls in an Web Api project. Removed Program Class and Main() from Program.cs. Project built fine, but EF add-migration command failed :-(
I would avoid doing this for API projects (or web in general). It can probably be done but I don't think the value outweighs the problems you will encounter.
@@IAmTimCorey Thanks for the reply! I was just playing with the new features. I agree with you. There is no point reducing a few lines of code from a web or api project. After a web or api project is created and built successfully, nobody ever looks inside Program.cs.
you're the first person that I'm saying this to next to my mom and dad: I love you
Thanks, but I'm married. :)
@@IAmTimCorey 😭
😂😂
@@IAmTimCorey 😂😂
Gay Talks 🤦
Anyone else having problems with getting C# 9? I have Visual Studio 16.8.2 already and installed .NET 5, but Visual Studio tells me I need to change to 9.0 and init is marked red. Changed the target framework in properties as well and restarted PC, did not help.
Nevermind, it works in the BlazorUI project that is set to .NET5, but it doesn't work in the standard class libraries targeting .NET Standard 2.0.
You need to make sure your project targets .NET 5. It can't target .NET Core 3.1 or .NET Standard.
Inline setters
My personal opinion
This feature is really a great thing.
Does it make the code more readable? I would say yes
Are we writing less code?
No not decisive for this feature.
I would say great.
I agree. I love this new feature.