I have been working with .NET since the heady, early days when the web framework was being called ASP-NG (next gen) and C# had not yet been given it's official name. I've written millions of lines of C# but sometimes I think it would behoove me to start over with C# as though I had never seen it before because there are things that have been added to the language in the last few years that I had no clue were there. Is there a course or book or blog post series along the lines of "C# for people who are writing C# like it's 2010"?
I was in a similar position, worked with C# from the beginning and recently switched to non-MS stacks. I found official documentation [1] easy enough to follow - I started with "What's new in C# 8.0" to the latest version.
[1] https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csh...
John Skeet's "C# In Depth" series presents how the language changes from one version to the next with code examples.
C# In Depth is indeed a good read. Unfortunately, the C# language is getting more and more complex, especially when you compare it to Java.
Java is catching up, and what appears easy at the language level, gets extra knobs at the runtime and lower APIs.
Sure, but it's backward compatible too. You can write C# 4 style code while in the latest version of .net/visual studio.
Resharper helps a lot with that, making useful suggestions.
I finally started using ReSharper for the first time and was blown away by the suggested refactorings/changes. I had no idea some of this stuff was even possible in C# -- and then more astonished to learn it had been there since 2012.
Iāve been using C# for about 12 years. I look at the new features and think of places where it would clean things up or how I could build a new feature. An example: I used readonly structs to replace regular structs that were being passed in by reference (boxing) and the new ref for readonly is a one time cost, both speeding up the system and reducing garbage generated.
I recently wrote a little cross platform command line app to tag my audio files [1] with C# (dotnet 6) and I must say: This language is awesome on macOS, Linux AND windows. I personally use Rider as IDE and it feels pretty natural.
The new features will make my C# life even easier.
Found out the other day the nintendo switch emulator ryujinx is written in C#. It's the first I've heard of a performant emulator written with a gc language and it's amazing. It's as fast as its competitor written C++ which goes to show that C# can be just as fast as language without a runtime with minimal gc pauses.
C# has a lot of performance oreinted features that are rare to find in GC languages. Value types and real Generics, of course, which helped during the dark years when the JVM was clearly better. There's relatively efficient and convenient interop with unmanaged function pointers and other helpers. Ref structs like Span make it easy to efficiently and safely pass around references to buffers rather than copies. In, out, and ref parameters and readonly structs help reduce unnecessary copies in function arguments. The .NET team has been optimizing the standard library using C# SIMD intrinsics. It's a great language for writing convenient code most of the time, and hyper optimizing where it counts.
Having done a fair bit of C/C++ interop stuff with C#, I would say this is definitely its standout compared to Java.
The things you mention are huge, along with "UnmanagedCallersOnly", the ability to write structs and mark them as meant to be used in interop code (see "Blittable/Unmanaged Types" proposal that was recently adopted), and the seamless "DllInterop" annotations for pulling in native external methods.
https://devblogs.microsoft.com/dotnet/improvements-in-native...
https://github.com/jkoritzinsky/runtime/blob/a5048c2fe5068e9...
The team that works on the native/interop stuff is top-notch, and they're constantly pushing boundaries and making neat improvements.
I'm more of a JVM guy, but credit is well due here.
Not familiar at all with this codebase, but one thing to note is that it does make heavy use of the unsafe keyword^.
I really like the removal of the !! operator from being included in the language. The syntax was awkward and the introduction of branching/exceptions into parameter spec felt wrong.
> The feedback and the wide range of insight we gained from this feedback led us to reconsider this as a C# 11 feature. We do not have sufficient confidence that this is the right feature design for C# and are removing it from C# 11. We may return to this area again at a later date.
But Microsoft bad, right?
Yeah they tried for like 2-3 releases but I think they are not happy with adding it. Language design is brutal: you make a mistake which you can never revert. And this group is mature enough to realize it.
Like DateTime. We are stuck with it.
Awesome. Our company is considering moving scientific applications from Python to .NET (C# or F#), mostly for stability reasons and better backwards compatibility.
We need to wrap C libraries though. Does anyone have experience with or reliable benchmarks for the C interface?
Itās pretty fast. Likely reason for that, MS designed both language and runtime this way since version 1.0. They needed that for their Windows Forms which consumes huge chunk of WinAPI.
I benchmarked a while ago when testing this library https://github.com/Const-me/ComLightInterop#performance On the computer I was using at that time (probably Ryzen 5 3600 CPU) the overhead was 15-20 nanoseconds per call.
I can't give you any benchmarks, but in my experience (from wrapping a big C++ game engine in generated C#), modern .NET interop overhead is basically unnoticeable.
.NET 7 finally also ships with NativeAOT which compiles your C# to native code that you can expose as a C library.
The Kestrel HTTP server included in ASP.NET was using libuv (async event loop implemention used also in nodejs) for a while (it is removed now and replaced with the managed `Socket` implementation. Since libuv is native code, they had a lot of PInvokes/DllImport in their glue code. The performance was way ahead of what they had in their IIS implementations, so I think you will be good performance wise.
I just turn my head to look at my bookshelf, and sure enough, there it is, my C# 6.0 & .NET Framework 4.6 book. That was the last version I worked.
Nice to read about all the changes in C#, I've been thinking a lot about going back to .NET, but at this point I would probably need some training. There are things like Blazor or .NET Core that I'm absolutely unfamiliar with.
I kind of miss Visual Studio for some reason, after what feels like a lifetime of web development in other open source tech stacks.
Iām perhaps in a similar camp, years of experience during the .NET 4 era, a lot of TypeScript and Rust after that.
Recently, I went back to C# for a smaller project. The .NET ecosystem certainly has its advantages compared to the āwild westā of NPM, which includes Visual Studio/JetBrains Rider.
My main problem was that the language feels so dated at this point. Why canāt I make local variables immutable? Why are there still no algebraic types? Why do the new nullability rules feel so inconsistent and tacked on, with āString?ā and āDateTime?ā behaving completely differently?
I realize not everybody cares about these āmodernā features as much as I do, but once youāve wired your brain to think about program composition in a way that simply feels better to you, itās very frustrating to go ābackā.
.
Edit: Itās not like the C# team is unaware of or in any way against these proposals. There just seems to be little visible progress:
Algebraic types: https://github.com/dotnet/csharplang/issues/113
Const locals: https://github.com/dotnet/csharplang/issues/188
I am sure you have heard this before, but F# sounds like it would be right up your alley. It has sane defaults (non-nullability, algebraic data types, etc.) while still targeting the CLR, enabling the usage of any normal C#/.NET library to be used within your application. Granted, there's _some_ friction going between C# and F#, but that is a small price to pay (IMO).
Fun thing is the current explaination regards readonly locals: https://github.com/dotnet/csharplang/issues/188#issuecomment...
It is basically: if we introduce it, it gives us a tiny benefit for a gigantic amount of noise during every single code review. It boils down to comparing developer productivity vs. language safety.
I find the argument a bit weak since code review guidelines can end this conversation AND C# has already quite some code analysis code fixes to auto-fix language usage stuff (like file scoped namespaces or nullability checks). And that case of const and readonly can be algorithmically checked.
Especially since its not really a language safety feature. As a reader of code I much prefer knowing what I need to pay much attention and what not. As a writer I want to be reminded when I promised myself to not touch a variable.
It does seem like a weak argument when it can be enforced/fixed by linters e.g. this is already solved in JS with eslint prefer-const rule
I suppose you can emulate it today with variable prefixes/suffixes and check the AST with a custom linter yourself
>Why canāt I make local variables immutable?
How it'd work in such a case:
You declare immutable variable "a" which's an instance of a class
and then you execute "DoSomething" method which mutates under the hood?
Compilation error? runtime error?
Anyway have you tried records?
It's usually on a syntactical level, to disable reassigning a value. For objects this means the reference is still mutable, value types are locked.
Js has const, C has const, Java final.
Imho it'd be awesome if mutability were not the default and we would have to mark mutability, but until then any variable that doesn't need it, is final. Which also helps skimming code
Iād be fine with semantics similar to readonly fields (and incidentally, āconstā in JavaScript): you canāt reassign the variable, but the contained object can do what it wants.
To your last question: Yes, records are really nice syntactic sugar for classes that want to behave like values.
For me, another gripe is: āWhy do I have to manage a csproj file?ā
Thatās one of the things that tangibly improved IMO: they removed the file list, so except still being ugly XML, the csproj is now very comparable to package.json or Cargo.toml.
Csproj is one of the better build config setups, I'd say. In practice, the IDE handles it all if you want. What would you prefer instead?
csproj is fine these days. sln on the other hand...
Itās pretty easy to pick back up and get in the swing of things - and very fun too. Lambda expressions and async programming might take the most study and practice to really feel comfortable using. Blazor server side is a new but very accessible paradigm, particularly with free component libraries like Radzen and MudBlazor. Dapper helps as an alternative for those not willing to go full EF for data access. Visual Studio 2022 is a nice, refreshingly automated environment. Azure has a ton of ridiculously fun tools like devops, key vault, functions, app service, etc.
Echoing the sentiment, I was a visual studio user for the best part of a decade, until Rider appeared on the scene. Rider/intellij is the new bar for developer tools today IMO.
but why?
I'm asking because I do use extensions like Roslynator for refactorings I'm not sure what I'm missing, what fancy Rider has?
Caveat: I'm writing C++, not C# but, Rider does out of the box what I used extensions for for the best part of my time working in Rider to start with. The IDE is faster to start up, faster to use, the tooling works better than the visual studio tooling, the licensing is sane, the source control integration is an order of magnitude better than VS's. The code completion for intellij tools is what you'd expect, for VS it's... varied depending on whether or not VS has parsed your project yet (and good luck figuring out when that is).
Code formatting tool support was substantially better (although still not ideal) in rider than VS, and VCS backed project settings mean that we can have developers auto format locally rather than building out tooling to enforce it.
Cross platform support, with remote editing is also a huge one for me. I have a windows workstation and a Mac as a secondary workstation. Before, I had to remote into the mac and use XCode to debug/build issues on the mac, now I use rider with remote support for 95% of my mac needs, and on occasion when I do need to drop back to the mac, I'm using the same tool rather than xcode.
Until 2022 (which granted I haven't used), VS was 32 bit which despite MS's frequent assurances wasn't a problem, was. Running OOM was a regular occurance on large projects for me over the last 10 years.
Roslynator is a collection of refactoring enhancements for VS. Resharper/Rider add a ton of things beyond refactoring. Its unit test runner is way better (IMO) than VS's native test runner. Support for Unity & Unreal Engine development for game developers. Rider works on Linux, Mac and obviously Windows.
I've been a happy R# customer since 2006. Since then I converted to JetBrain's all products subscription - DataGrip is a really nice database management GUI that supports nearly every database you could ever want (from SQL Server to Postgres to MongoDb!) If you do any frontend development Webstorm is IMO a much better experience than VSCode.
Rider has all of ReSharper but without the performance hit that you get in VS + ReSharper.
If you want to come back and dip your toe in the water, Visual Studio 2022 is better than ever. But Rider is a great IDE and Iād recommend starting an evaluation of that.
I feel like 2022 is the slowest edition I have used. My 2017 instance is still significantly faster. I've also had a hell of time with "Hot Reloading" and even the debugger in general.
Why oh why does C# still not have sum types? It is by far the most useful feature still missing from C# and one of the key reasons why I prefer F# over C#.
Useless features. What C# really needs is the following:
- Discriminated unions
- Switch expressions as standalone statements
- Type providers, so it will verify the content of the text, provide syntax highlight, autocomplete, etc for many languages and data structures:
var sql = <SQL>"""
SELECT Id, Name FROM Users
"""- Pipe operator to avoid nested method calls (similar to F#)
Get a daily email with the the top stories from Hacker News. No spam, unsubscribe at any time.