My favorite .NET 10 feature so far is not within the .NET library itself, but `dotnet tool exec` to run C# files as scripts without a build step. This has been available in F# for a long time via `dotnet fsi`, and for C# also via the third party cs-script tool. It took a surprisingly long time to officially reach the primary .NET language!
I only really wish C# would’ve been directly integrated as an alternative scripting language in PowerShell. You may balk at the idea for causing a ton of cruft for people who don’t need it; ”a whole new scripting language!” But the thing is — PowerShell already builds upon .NET so supporting a new language is a rather small effort (relatively speaking) if it happens to be a .NET language. And C# just feels so much better for me to code in when the scripts grow in size. I’m not sure I’ll ever become friends with the implicit returns. C# has become particularly suitable for scripting with the recent developments in the language: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals...
"dotnet tool exec" is so you can run third party command line tools like csharpier that previously required "dotnet tool install" before you could use them. For example, in https://csharpier.com/docs/Installation you can now simply do "dotnet tool exec csharpier". This is like "npx" in the JavaScript world.
The .NET team said they're working on VS Code integration. LinqPad still has some unique features (mostly database related), but at least for me, VS Code + dotnet run will be sufficient for my needs. Worst case, I can just throw a breakpoint on my database IQueryable result.
F# has been a third class citizen for a long time... Last I heard the entire f# team was ~10 people. Pretty sure "find references" still doesn't work across c# and f# (if you call a c# method from f# or vise versa). That also means symbol renames don't work correctly.
I agree, but somewhat paradoxically, F#’s lack of new features kind of becomes a feature. Have you seen the number of C# features added in the last 5-10 years? It’s crazy
Now I'm curious if C#/.Net 10 is smart enough to ignore the shebang line. Personally, I've tended to use Deno/TS for my more advanced shell scripting... the main runtime is a single executable that works fine in user context, and dependencies can be loaded/cached at first run.
Of course, with C# as a shell script, you'd likely be limited to just in the box libraries or have to setup a project for sake of running a script, like I've had to do with Node or Python stuff.
It's great that Microsoft added this as an official feature but there has been an open-source third-party solution that does exactly the same thing for a long time: https://github.com/dotnet-script/dotnet-script
I've wanted this for a long time. After reading this link, and the MS release announcement, I still don't understand what a "tool" is, or how you can use `tool exec` to run a single *.cs file. Is there a straight-forward recipe anywhere for doing this targeted at absolute simpletons?
To boil it down: you create a console app, add a couple of attributes to the solution file (https://learn.microsoft.com/en-us/dotnet/core/tools/global-t...). Packaging and publishing to nuget (if you want to share with others) is via `dotnet pack` and `dotnet nuget push` with some flags.
I do have to say it's actually very well documented.
Sorry for being unclear. Using tools isn't my goal. I want to run a single *.cs file from the console. It may be possible to achieve this using tools, but I don't know how. I did read the resources I could find, and didn't find any information about this.
You’re right that it’s missing this new functionality. The blog post has some details to get started, but I’m guessing that a docs link or section is missing for that.
Dotnet covers quite a bit so the docs are accordingly larger than other projects that have a smaller scope. I will say though that while hit or miss, on average I’ve enjoyed their docs more than the average project.
Sorry for confusing you. I can't edit the post now. The command is dotnet run script.cs. The tool stuff is about something else unrelated; NuGet installable CLI executables.
I agree. The stability comes from its ecosystem though. Enterprise Software. Where things like meticulous use of Omit and Task are common place and really REALLY bad things happen if you fuck up.
But besides that, there’s a healthy gamedev community that embraced C# early and have been using it ever since. There’s C++ MFC guys that got duped into WPF and have been supporting it ever since. Winforms devs that are still trying to make a dark mode. I’ve even seen community grass roots “I need this in Silverlight” projects take hold and become one of the largest SDKs in the world. It’s cool. It’s fun. And with AOT, it’s everywhere. C# is like that cool uncle of your Father (Java) that likes to party all night but still holds a job. Maybe someday TS.Net will exist and we’ll all be singing “Back in my day”
I very much doubt about TS.Net, given the rewrite in Go decision.
.NET nowadays has a serious adoption problem, and they should spend more time talking with their own colleagues at Azure, about their use of Java, Go, Rust.
The issue was in the beginning they didn’t think interop with C/C++ was value add. People complained and they added “Managed C++” which unfortunately influenced C++03’s design a lot. It wasn’t until C++11 that Microsoft gave up. You couldn’t effectively interop with C++ without writing a managed C++ wrapper, which only worked on windows. They added support for P/Invoke to aid in Win32 calls (shell.dll, user32.dll) as a simple fix and we went nuts for it. Wrote wrappers using P/Invoke and a config map nightmare of which dll’s, or dylib’s, or so’s, you needed to get the form to show.
Fast forward to today…
Rust can interop with C natively. Go can as well, though you’re bringing your luggage with you with CGO. .Net hasn’t ever really had that kind of focus. For one, IL, two, Microsoft saw the platform as a cash cow, three, ecosystem lock in allowed a thriving “MVP” contractor community.
You're clobbering together a bunch of different stuff and not making a ton of sense. C and C++ are very different languages, and that's especially true when doing interop with them from other languages.
For C-based libraries, P/invoking is trivial in C# and has been around forever. And it's cross-platform, working identically on Linux and macOS. I have no idea how you can say ".Net hasn’t ever really had that kind of focus" when it's been a core part of .NET from the start, and .NET relies on P/Invoke to do everything. Go look at all the DllImport() statements in the .NET reference source. Rust FFI is nearly identical in implementation to C#. Go has a slightly different implementation with the CGO module, but whatever, it's close enough. Just step back and remember that, in general, calling into C code is trivial in every language, since it has to be: all these languages will eventually have to hit libc / user32.dll / whatever.
C++ is a totally different story. You can't work with C++ libraries with P/Invoke, that's true... But you also can't work with C++ libraries using Rust or Go, either. Nor Python, Java, Javascript, or really any other popular cross-platform language.
C++ dynamic libraries are really challenging to call into for a variety of reasons. Virtual functions, multiple inheritance, RTTI, name-mangling, struct/class layout, vtable placement, ABI differences, runtimes, etc all make calling into precompiled C++ libraries a nightmare.
In fact, the only way I know of working with pre-compiled C++ libraries is with languages that target specific operating system / compiler collections. E.g., Objective-C++/Swift from Apple, and C++/CLI from Microsoft. These are obviously not cross-platform solutions, since they depend on knowing the exact compiler configuration used to build those libraries in the first place.
For every other language, you either need to manually build C shim libs that you can call into using the C-based approach above, or if you have access to the C++ source code, creating wrappers around it and building it into a module (for example, using pybind11 in Python).
The only reason is name mangling. You can disable this or export declspec it and keep the C-like signature. Painstakingly recreate the API in C#, using P/Invoke, and hope for the best. It wasn’t until late 2015 that we got codegen to “automate” this, or roll your own.
My perspective is from a first adopter, not an insider, 24 years ago, so I can’t speak to motive but as a customer, it felt exactly as I described. The documentation around P/Invoke was lax, you were shoved “Managed C++” down your throat by your rep, and any dream of going cross platform died in that meeting room until Miguel De Icaza did something about it.
It certainly is not, it is quite common to use templates directly or indirectly via the C++ standard library, and P/Invoke cannot handle those.
Also during .NET 1.0 days, Microsoft had a Website where you could paste any well known Win32 API or related SDK, and it would spit the annotations.
What was never as good in .NET as it was in VB 6 and still is in Delphi and C++ Builder to this day, was creating and consuming COM, which is kind of annonying given how much Windows team loves it.
At least it isn't as bad as the multiple reboots in C++, which I will keep asserting that from all of those, MFC still has the best tooling to handle COM.
P/Invoke was born as J/Direct on J++, it became P/Invoke after the lawsuit, and Cool project turned into C#.
Managed C++ Extensions in .NET 1.0 got replaced by C++/CLI on .NET 2.0, it was a .NET Core 3.1 milestone to support it, and has recently been updated up to C++20, minus modules.
Still heavily used among .NET community on Windows.
Meanwhile the native C++/CX and C++/WinRT, both failed their adoption efforts.
Interestingly, the Rust windows crate is generated from an MSIL assembly. And same metadata might be used to generate C# bindings thanks to cswin32 [1] project. The meta-assembly generation (Win32 metadata project) is based on clangsharp and it's fairly straightforward to generate interop code for native Windows libraries. Some time ago I described this process on my blog for the detours library [2]
Windows and Office never adopted .NET for client code in the first place except for the Longhorn period in the mid-00s, which burned them and put them off it. If that didn't stop .NET in the two decades between then and now, I'm not sure why it would today. Actually, Windows is just now starting to adopt C# now that AOT is supported (I think the new native Copilot app is C#).
Many Windows Server admin tools (such as Server Manager or Virtual Machine Connection) and MMC snap-ins (e.g. Event Viewer, Hyper-V Manager) are written in .NET Framework 4. PowerShell is .NET Framework 4. Everyone’s favorite bloated IDE (Visual Studio) is .NET Framework 4 as well.
In the Office land, Excel’s Power Query is .NET Framework 4.
Adopting the modern .NET is probably harder due to its lifecycle.
OMG could you imagine writing MMC snap-ins using some sort of plugin declspec import bs in C++? .Net and reflection with Assembly.Load saves so much time and effort to build modular “ship it now, deliver features later, extend it if we fall behind” apps. Not that those are good things, it just means you can defer until your MS PM gets the budget to fill those backfill positions that have been open for 12 months because the hiring bar is astrophysics
Anders Hejlsberg, a main architect on C# & TS, stated somewhere that they re-wrote the TS Compiler in Go because the syntax was the closest to how it was originally written and allowed re-writing to be easiest. He has a great write up of it somewhere on GitHub.
Microsoft is an insanely huge company. There teams seem to be able to use whatever works best for the project/team.
The old XKCD comic of org charts in big tech shows Microsoft as a bunch of people aiming guns at each other for a reason. They'll have 5 teams making 5 competing products sometimes. That's the culture I'm aware of. I'm not aware of the dogfooding culture you are suggesting.
Yeah, and then at BUILD 2025 session, he ended up explaining how they had to rewrite all the data structures, due to the less capable type system from Go versus Typescript.
So the gain isn't as much as what is being sold.
Meanwhile Azure has no issues using AI based translation to port C++ projects into Rust, which they could have done in a similar way to port into C#.
Also, Go has a less capable tooling as C# for WebAssembly, due to Blazor efforts, the team has invested quite a lot into it.
It remains questionable what will they do for the in browser playgrounds and editors use cases.
Not sure I agree on the adoption problem. A few medium sized client projects are nothing compared to the massive internal .NET codebases Microsoft has that run some of their largest services.
C# has been around a long enough time and Microsoft's teams over that time have done a pretty good job making upgrading each version easy.
As long as the current leadership in the C# & .NET teams remain, it's a very safe language and framework to use. They also deserve huge kudos to API & performance improvements the past decade since moving on from .NET Framework 4.x, which still runs fine.
They also have a lot of internal & external users using it.
Oh I learned this the hard way. Managed DirectX, XNA, Creators Club, Windows Store, shared profit motive, fair business practices, Project Natal/Kinect, Azure, and finally… .Net. Yup, Microsoft loves developers… loves their subscriptions.
I blame historic microsoft for their anti-oss stance. It kneecapped the .net ecosystem for over a decade and created an attitude of "if it isn't in .NET, I won't use it".
That has certainly played a role, however that is common to Windows development culture in general.
The 3x "Developers !" meme isn't for nothing, Microsoft just like Apple (and NeXT), always a full stack development experience story.
Everything that one needs is there on the full Visual Studio Professional, and then there was the ecosystem of small indie developers and MS Partners building on top of that.
That is quite different from UNIX FOSS culture, and has also been a friction point to those that went Apple without understanding that also have that on their DNA, regardless of OS X foundations.
I agree as well. The hostile attitude towards OSS under Ballmer led to this. Nadella had the correct approach and a year later, started repairing those bridges, joining the Linux Foundation.
Many things under Satya also feel like good old Microsoft, like lack of GUI frameworks for GNU/Linux, killing VS4Mac after the rewrite, dotnet watch drama, profiling tools being VS only,...
MAUI not supporting Linux feels like such a huge whiff. It is clearly possible to get at least decent cross platform support that includes linux in .net considering Avalonia exists.
MAUI is supposed to use native ui components, AvaloniaUI just uses Skia.
I think going with a non-native approach would kinda make Linux a clear second class platform, especially with all the native features that need to be rebuilt?
Is there any multiplatform ui framework that's actually "native" for all the different linux ui toolkits?
VS4Mac deserved to die, that was Mono Code aka Xamarin and it was terrible. No offense to Miguel, mono is amazing, but the IDE they made was horrid.
Microsoft was asleep at the wheel the last decade of Ballmer, leaning too heavily on their Xbox Studios and Enterprise Cloud to care about desktops. They gladly let Mac take office share as “no enterprise software developer would ever choose a Mac”. Those famous Mac vs PC ads.
The GUI development story has plagued us for a long time. No one wants to take on the challenge of a unified user interface spec. Why? Because it will always be wrong - ever changing - and a giant suck of corporate resources.
It’s better to let each team think of their own way of doing things. Then, they can choose the best of them and release them as frameworks (WPF) only to be abandoned by the next regime change.
MAUI, UWA, Metro, WPF, all an attempt to save what effort they have made. Ultimately, everyone loves their Electron apps, so HTML has become to new UI paradigm. They move too slowly. Convinced “they know better than you” and will spend the next 5 years hyping up the next XML abomination.
Since you mention great CLI - is there a CLI tool that is free/cross platform that works like prettier ? I found https://csharpier.com/ but have never heard of anyone using it.
Also not sure how it works with linters like roslynator or stylecop ?
This is something I miss very much when coming back from TS, other languages also have better formatters. C# is very tied to editors/IDEs which is a nightmare in teams where some people use vs/vs code/rider
Csharpier is the best option available. I've been using it for 3-4 years now and had success getting it adopted at my last two companies on greenfield projects. It's not exactly an unknown tool - nearly 2k stars on Github. But a lot old school .Net companies just don't seem to have much interest in auto formatters because they've been working without them for a long time.
If you're using csharpier you don't need to use Roslynator formatters. No issue with the analyzers package. The csharpier docs have info on what StyleCop rules need to be adjusted so they can work together. Personally I don't use StyleCop anymore as it seems to be fairly dead, and I don't really feel the need for things like enforcing file layout or naming.
Edit: Also I will add that unless the landscape has changed recently, I believe csharpier is the only C# tool that has deterministic formatting good enough to enforce code formatting checks in CI.
dotnet format [0] exists and is maintained by the .NET team. It is different from Prettier in that it is much more configurable, but it gets the job done for us. It does integrate language services and can automatically apply code fixes for custom analyzers. I have not explicitly tried roslynator or stylecop, but I suspect this would work as expected.
I was not able to use (recent) dotnet-format as standalone .exe tool, also it only worked if inside an actual project with .sln/.slnx file and all that. I could not instruct it to work on single file.
> It is different from Prettier in that it is much more configurable
I only tried it briefly but found it was waaay to lenient with the amount of variance in style it left unchanged (eg line breaks for function parameters) - can it get configured to produce consistent formatting like prettier ?
I think there are also a lot of default rules which aren't enforced until they're bumped up in severity in the .editorconfig.
Also it can hook into roslyn analyzers, so if you want a more opinionated analyzer then stylecop analyzers ( https://github.com/DotNetAnalyzers/StyleCopAnalyzers) would be an option, although I haven't used it myself for a long time.
It can be configured to be much more aggressive with formatting, but I'm not certain if you can force it to produce the exact same output for any possible whitespace in the input.
Hi! I use csharpier, it does the job - I included it as a preliminary check in our CI pipeline for a step of merge requests quality assessment. It is the closest tool I found, that ressembles prettier. You should definitely give it a try.
For the last few years, I’ve been developing CAM/CAE software on my job, sometimes embedded Linux.
Same experience: last time I developed software written entirely in C++ was in 2008. Nowadays, only using C++ for DLLs consumed by C#, for 2 reasons: manually vectorized SIMD for CPU bound numerical stuff, and consuming C or C++ libraries like GPU APIs, MS Media Foundation, or Eigen.
Sometimes I feel like there ought to be a Hacker News like forum for us dinosaurs stuck in the Enterprise tarpit. Instead of talking about Elixir and AWS startup credits, we’d complain about the weather and legacy CORBA components.
I've been using it since 2002 so you can imagine my opinion when jumping to other languages. They've been very good to steal all of the things that worked from other languages and constantly iterate on their core infrastructure and language.
Do you know about any sizeable open source projects written in C#, other than what Microsoft has produced? I rarely come across anything written in it.
It's a curious thing, the .NET ecosystem. The overwhelming majority of it's ecosystem seems to be dominated by Microsoft first-party libraries and frameworks. 3rd party libraries and frameworks seem to either get swallowed up by Microsoft, killed, or never reach critical-mass.
Often in the .NET ecosystem, it seems there is exactly one library or framework for thing $X or $Y. Whereas in the JVM ecosystem, you have 30+ logging libraries, 87 different MVC frameworks, etc. (yes, I'm being a bit facetious, but you get the point).
I imagine .NET developers often think this is a good thing, in regard to their ecosystem. No guessing what to use, just go with the "blessed" path and don't think about it. And, to that end, there is some obvious merit to this.
However, I feel the .NET ecosystem loses out on cross-pollination of ideas. There's zero possibility Microsoft's employees just happen to make the best frameworks and libraries... there should be many web frameworks - each competing for mindshare and trying to out-innovate each other, each with their own pro's and con's, etc.
So, while .NET might be technically open source, it still feels rather like a closed source ecosystem, controlled by a single corporate entity.
Libraries getting swallowed up is not so bad as it sounds. For instance for web frameworks there was a phase of experimentation with projects like Nancy that inspired changes for asp.net core. There is still alternatives like fast endpoints.
Also you have things happening like integrated system.text.json replacing newtonsoft.json that over time took on some cruft.
Why would anyone make a .NET open source library when Microsoft is quick to squash anything that is actually useful with their own open source implementation?
Microsoft still has some lessons to learn about fostering an active open source ecosystem -- of course, unless they are intentionally suppressing it in .NET.
Can't speak for FLOSS, but I've worked on massive projects in various Banking, Govt and eLearning spaces. I've never really hurt for library support via NuGet either. It's honestly not always my first choice, but pays the bills.
I mostly just dislike a lot of the excessive use of "Enterprise Patterns" for projects that don't come close to actually needing them.
It is a self-fullfilling prophecy: No big open source without motivated contributors, no contributors because of bad rap because of no big open source projects.
It is not technology what holds .NET back. It is also not politics (nearly all languages have evil overlords). It is people who hold up to statements like: "I will not touch .NET with a 10-stick-pole"
Not sure what your definition of sizable is. But if it’s just physical size of repo then my language-ext project [1] is about half a million lines of code, ~7,000 stars, and ~25 million downloads.
I liked .NET but the performance was really bad for anything that had even reasonably latency requirements. But this was 15 years ago, so maybe it has improved. I don't remember exactly what I wanted to do but it was something like pumping some event every few milliseconds and it was basically impossible. The jitter was already larger than the interval.
> .NET was the most sane programming ecosystem that I worked in.
Having written libraries in .Net I fully disagree with that notion.
First insanity is figuring out what in the fuck you need to support. .Net framework or .Net standard or .Net Core or Mono (or .Net Duplo or .Net dot nes :P).
Second is the Source generators. I swear using t4 templates is the saner option. I've had cached artifacts appearing out of the fucking nowhere like unkillable zombies despite closing the Rider, clearing its cache, and killing build server.
Third is the availability of packages. In Rust and Java there are like several libs for anything (even if C bindings).
> First insanity is figuring out what in the fuck you need to support.
Since I no longer support .NET Framework, it's just .NET now.
.NET was two platforms for a while and they did a lot of weird stuff to make that work (.NET standard) but it's been one platform for many versions now so that specific difficulty can mostly be ignored.
Easy to say, but it poiets to ecosystem fracture. But I've been getting requests to support really weird and outlandish versions. Stuff like Mono and .Net 4.56
Most C# libraries I use are outdated, crappy and do just a little less than what I need. Also, most Rust libraries I try to use are outdated, crappy and do just a little less than what I need. Maybe what I need is niche but my experience is pretty similar in that regard.
All I want is for dotnet watch to behave in a predictable way. In .NET 9, even when using —no-hot-reload, sometimes CSS changes to components are not picked up on Blazor components.
It’s so aggravating because ASP.NET with server side Blazor components really has it all: type safety, server-side components ala Astro, fantastic ORM model, great runtime perf. But this little issue makes dev quite tedious at present: did I mistype a Tailwind class name, or did dotnet watch miss the change?
I inherited an MVC app that has a bunch of jQuery rendering crap and I would like to move to server side components - since you seem to be into Blazor Server side - have you heard of HTMX ?
What would you say would be the benefit of Blazor vs HTMX and Razor Pages for subviews ?
My experience with Microsoft UI toolkits after winforms, is that they are all janky over-engineered stuff (Silverlight/WPF/Xamarin/Maui) terrible tooling and support compared to alternatives. And Blazor using websockets makes me believe it is the same. The compile to WASM idea is a typical example of this.
So what would be the selling point of Blazor ? It feels like you are just bundling stuff into Blazor magic when you could KISS with something simple like HTMX ?
I still haven't found a use-case for the websocket Blazor Hybrid and it still smells so much like the worst mistakes of the original ASP (before .NET) and the `runat="client"` versus `runat="server"` confusions.
Blazor WASM makes some sense if Silverlight ever made sense for a project: it's a way to ship C# directly to the browser for maximal code sharing with other C# projects in a C# ecosystem. It's basically "what if Angular/React was just Razor Pages running on the browser?"
It's absolutely the opposite of KISS, it's lifting and shifting the entire .NET runtime in WASM to the client. Outside of corporate networks and packaged apps like Electron or Tauri, I'm not sure it makes any sense. But if you like writing Razor Pages and wished they ran closer to the client metal, and you can afford the bandwidth of an entire .NET application soup-to-nuts as your SPA framework, there is a sense to it.
If all you think you need is Razor Pages with HTMX that's probably all you need.
>I still haven't found a use-case for the websocket Blazor Hybrid and it still smells so much like the worst mistakes of the original ASP (before .NET) and the `runat="client"` versus `runat="server"` confusions.
That is exactly my read of it, especially given Microsoft track record on delivering with stuff like this.
Not sure about the Silverlight comparison - in the days of Flash, browsers did not even have a way to stream video reliably, nowadays it just cramming a square peg in to a round hole - heavyweight runtime built on multithreading crammed to a single threaded event loop. I have not tried it - but after using .net in much more powerful/native envs like Android - I know for a fact that the iteration/build/debugging story sucks compared to native JS/TS. Also as bad JS is, TS makes it saner, tooling has matured and DOM APIs are built for JS.
> nowadays it just cramming a square peg in to a round hole - heavyweight runtime built on multithreading crammed to a single threaded event loop
Sometimes the "event loop" part is forgotten because JS' single threaded thing is very "cooperatively threaded". This is a large part of why async/await works so well in JS and is growing so quickly in adoptions. .NET's multithreading is built in a way to excel in "cooperatively threaded" environments (its task pools are cooperative by default, for instance, and also arguably heavy use of async/await was C#'s idea first).
It would be great to see more WASM multithreading powers, but writing C# for today's WASM environment doesn't feel that different from "regular" multi-threaded C#.
> I know for a fact that the iteration/build/debugging story sucks compared to native JS/TS
WASM debugging is nearly great, including growing Sourcemap support. The ability for Visual Studio to be the Debugger interface to Chromium-based browsers is more powerful that ever. Certainly in its debugging story Blazor WASM is much advanced from Silverlight which was only really debuggable in IE and then was still often flaky.
> DOM APIs are built for JS
There's still talk of making more direct DOM APIs for WASM. Might be interesting to see eventually.
This is why it is so easy to relate Blazor WASM to React. Blazor is essentially using Razor templates to define a Virtual DOM which it then sends render updates across the WASM/JS boundary to a very tiny virtual DOM renderer.
It's not what I'd use for smarter direct DOM work, but in comparison to React it gets the job done and works surprisingly well, even with the language barrier and data marshalling across sandbox layers.
I've used Blazor WASM on Enterprise projects. I'd probably use it again on Enterprise projects. It can be real nice to have backend and frontend all entirely in C#. (In different projects. So that you can scale them independently if nothing else.)
As of today (and going forward), there are two different flavors of Blazor server-side rendering. There is the original version where the component is rendered on the server and interactivity is provided via websockets. Now there is also static server-side rendering, which works very similarly to razor pages, pages/components are rendered on the server and there is no interactivity. You can then, of course, add interactivity wherever you'd need it with server-interactive or webassembly interactive sub-components.
I wouldn't necessarily say there's any benefit of Blazor over HTMX, it just depends on what you're most comfortable with and what works for you in your project. But you could architect your front-end in a similar way where you have small blazor components in your pages with interactivity.
I think Blazor is in a nice state now, where I can iterate very quickly on projects with just static server side rendering and add interactivity whenever it's needed. It gives me a very fast website, rendered on the server, and the option to add some interactivity whenever I need.
Blazor static server side + HTMX is probably the only way to make a cost efficient and performant version of Blazor suitable for public websites. WASM is way too big and slow, Websockets take up server resources and cause problems with timeouts where the user has to refresh their screen losing all state.
What would be the benefit over Razor pages tho ? Component model ? Feels like partial views and razor templates might not be the cleanest/dry-est solution but would make the implementation super straightforawd.
Yeah there is basically no real difference between MVC or RazorPages or BlazorStaticServer pick your poison depending on your preference. Personally I wish the .NET team would just add components to MVC and RazorPages then we can forget about Blazor.
> It’s so aggravating because ASP.NET with server side Blazor components really has it all
Agreed. I bailed on Blazor over the tooling experience. Editing components in VS2022 was so janky for me. Syntax highlighting and intellisense never worked correctly.
I don’t think there’s ever been any good tooling for the entire collection of ASP.NET DSLs. Be that MVC, Razor, or Blazor. Genuinely the same problems I had in VS2010 still happen in VS2022.
There’s been some changes and improvements, but I really have to ask what the editor tooling team within that team are doing.
I know there are some very difficult problems involved in parsing and formatting and highlighting bastardised mixtures of HTML, C#, and JavaScript all in the same file but if anything I think that perhaps suggests it was a bad idea to begin with.
Consider the tooling for desktop and mobile apps with XAML (WPF, Avalonia) or even WinForms - they all have code behind support.
Meaning there is no need (or ability) to mix all three in the same file.
We have had great success with Maui Blazor Hybrid. Each release hot reload gets better with fewer edge cases. I also found that having a separate .cs file instead of in one file helps with highlighing and intellisense.
I hear a lot of complaints about dotnet watch, but my experience doesn't match. I just use it from the terminal (instead of running it from an IDE) and it mostly just works.
All these changes, yet still no satisfactory UI framework.
Still no migration path from WinForms to something modern.
I love .NET but if you're taking on an older desktop app that is still using VB.NET and WinForms it feels like Microsoft have decided to let you circle the drain with no supported way forward into MAUI or whatever stupid XAML UI they decided is the solution these days.
On a server, .NET is fantastic and it's entirely possible to build and debug your system on Linux with no loss of productivity, but the desktop stuff is bad and getting worse.
I've tried each iteration of UI paradigm they've tried since WinRT and never really had any significant problems with any of them. WinRT, UWP, WinUI, MAUI...
But then they aren't even willing to invest the time to dogfood their own products and fully replace the windows UI. Really doesn't inspire confidence.
I suspect they also made a bad bet by going so hard on blazor without putting more support behind WASM itself. Now that's stalled out with WASM's own failure to reach critical mass.
Microsoft has zero vision in the UI space. It’s crazy that there isn’t there a single, obvious solution for developing Windows applications in 2025.
I agree that it seems they’ve made some bad bets and now are bogged down supporting half a dozen different frameworks with different limitations and tradeoffs.
They keep trying to reinvent the wheel, but it doesn’t seem like they’ve ever really meaningfully improved on WPF.
At least there is Avalonia for an open source, cross platform WPF alternative. It seems like the sanest way of making desktop applications with C# currently.
That would be a first, not having significant problems.
As someone that was deeply invested into WinRT since Windows 8, and went back into distributed systems and Web after all the disappointment regarding how managemetn handled it.
Everyone on the Windows development ecosystem has had enough from the multiple reboots and tool changes, UWP never being as good as WPF, WinUI iterations even worse, the team now went radio silent, the last community call was a disaster,...
Sorry, to be clear I meant no significant problems with the tech.
Sure, it was opinionated tech, but that would’ve been ok if they had stuck with it like C# itself and fleshed it out more, which only would’ve happened had they implemented the entire OS in it. The fact that they couldn’t is in my mind the exact reason the tech failed.
I agree with your point of view, this was the second coming of Longhorn, WinRT was after all pushed by the same folks that killed the Longhorn effort, those on Windows team that sided with Steven Sinofsky, using COM in Vista as future foundation for .NET ideas in Longhorn.
The Hilo tutorial for Windows 7 remarks regarding C++ are quite telling of their point of view, on which programming language one should be using,
"The rich user experience of Windows 7 is best accessed through a powerful, flexible language, and that means C++: by using C++ you can access the raw power of the APIs for Windows 7."
Joe Duffy has some remarks on how even with Midori running Asia Bing infrastructure, and proving workloads in front of the Windows team, the reception to it was rather cold.
Eventually he left MSR and created Pulumin on top of Go.
Meanwhile Apple/NeXT and Google, decided to push languages like Objective-C, Swift, Java, Kotlin, over classical C and C++, proving the point that change is possible if management is willing to support the team, even if that is a very long run.
See Apple's Metal Swift bindings, versus Microsoft's Agility SDK for DirectX.
Assuming the web is not an option for whatever reason.
I did some Win32 interop recently and found it to be refreshing. It's definitely lower level and more difficult, but it will outlive all of these other paths.
Using tools like cswin32 makes this a lot more tolerable development experience from managed code.
Only thing I want to hear about lately is the next major version of Visual Studio, I feel like it will never come. I always feel like every major version has drastic improvements, and I'm starved for them.
They’re consolidating the tech with SQL Server Management Studio, last I heard. I think they mean to get the rewrite of SSMS out this fall, but I may be misremembering. A new major version of VS is probably coming, although I must say I’m pretty pleased with the current tranquility.
You can divide visual studio into 4 era's. The vs6 (we smashed all of our dev tooling together and its integrated decently) era, the vs2002/vs2003/vs2005 (we broke it all and you will like it and never speak of C++ again), vs2010 era (we fixed all of that from 2002 sorry about that), vs2017/vs2022 (it updates from the internet and takes forever to install and now does everything).
The problem is MS is unwilling to stick with anything dev wise. The whole ecos system is a littered realm of half forgotten techs that may or may not be supported anymore. Wrapped with very confusing messaging to the devs what to use.
I prefer VS Code... though MS has for better or worse kept the .Net tooling relatively weak. I'll use Rider or VS on a few occasions... then retreat back to Code as much as I can.
For split web projects, definitely work on the web ui in VS Code.
This saved so much time, space and support - where previously we had to recompile stuff, and if you had Maya/MotionBuilder/etc plugin it had to use the right compiler.
Also now even with newer IDE you can instruct the project to use older (or even better - a specific) version of the toolchain.
It also solves a more subtle problem - when people install a tool globally they install latest _at that time_. But the world doesn't stand still, and things get updated. `dnx` always uses the latest available version by default (you can of course pin with `dnx <package>@<version>`) so that you never get out of date.
I haven't used C#/.NET since .NET 4 - I remember it was great, yet heavily tied into Visual Studio, and forget about using CLI for things like most other languages. It was all GUI or nothing. Insurmountable XML files.
How are things these days with .NET 10! Jesus, 10!
Dudes who use it daily, what is your favorite feature you think?
Favorite recent language feature is a big investment in C# pattern matching. It's a big feature from the functional programming world rare to see in "Enterprise" languages.
Favorite recent runtime feature is all the cool low level stuff opened up by Span<T> (and Memory<T>). It has a similarity to Rust borrowing, but well integrated into the CLR's existing type system. It has opened all sorts of performance code possibilities that is still memory-safe/type-safe with fewer needs for falling back to "unsafe" operations. This is not just exciting because it is an interesting playground if you like low-level programming, but also because it has been a performance flood lifting all boats in the .NET ecosystem. A lot of code over the last few years has gotten easy performance boosts by just recompiling (because the compilers were taught to prefer Span/Memory overloads when they get added; no change to C# or F# code, just the compiler picking a new performance path).
Definitely change for F# code, some of those Span overloads broke type inference. Also, certain APIs even removed their non-Span overloads between .NET versions, which was a straight up breaking change for every language other than C#.
Very different. That was the .NET I knew in college, .NET Core really changed the game. I personally use CLI just for EF Core (ORM) but Rider support is there so you're not tied to VS.
My fav feature is honestly how little boilerplate I need compared to Spring Boot and the syntax sugar is honestly really nice.
My favorite feature, especially considering the past of "heavily tied into Visual Studio" is the platform independent nature of (most of) "modern" dotnet. That is to say, I run Fedora on my laptop, and I do not want Windows, yet I don't feel like a second class citizen and dotnet runs well and is available from repositories that Microsoft provides for various Linux distributions (it just hit me how strange this is, for _Microsoft_ to offer official repositories for Linux operating systems...).
I also really like that its development is fairly open (it's on github).
From a more technical point of view, I think C# is a slightly better Java. A pretty nice language overall. It's not gui-or-nothing with dotnet core so it's not too difficult to create workflows for ci/cd pipelines, although the .net framework solutions we still have aren't too much harder to script: msbuild is pretty capable.
The version numbers used to increase much more slowly. Since the .NET (modernized / cross platform) core "track" the version number increments every year.
The version increments roughly every 6 months. It's almost the exact same update cadence as NodeJS: LTS versions are even numbers released in the Fall and STS versions are odd numbers released in the Spring. STS often focuses on "bleeding edge features" and LTS often on performance and stability. (Though both are year round projects and there are bleeding edge features in an LTS and perf/stability fixes in an STS.)
It's still stuck in weird formats and monoliths. A lot of GUI-only stuff has been ported to the mega CLI, but it's still the weird Visual Studio format plus XML files that you cannot replace with a simple Makefile. You still can't just compile a bit of C# as-is, it must have the Solution, Project, Assembly etc. chain, the run-as-script feature is nice (lots of cheers when that was presented! even on the live stream), but it's specifically not designed to allow you to assemble a toolchain that works for what you need. There is only one and it has everything, no options.
The question, of course, becomes: when does that matter? For a lot of people who are in to .NET, they see that as a benefit. Look at Go through this lens, and it's similar; the go CLI is the compiler, linker, package manager etc. I suppose the biggest difference is that it doesn't prescribe solutions and projects and file formats to go with them, which enables you to put this in any existing CI, make or other system.
Yep, but you still can't say "compile and link everything in this tree". Technically, the language can, but the framework assumes specific compiler, linker and layouts on the filesystem so at that point you can't. It really wants that editor-related stuff to be part of the framework, and everything else has to bend for it.
A Project file today can just be a full tree glob. New projects start out in that form. The `dotnet` CLI is still going to assume some default output paths as it builds object files and executable assets, but those are all easily flag configurable today. (I've done some wild CI things.)
You don't have to use a Solution at all with the CLI, you can do everything in a single Project and one full tree glob. (Technically you haven't need a Solution with Visual Studio for a long while either, if you don't mind it sometimes auto-creating them at compile time, and even then you can just .gitignore .sln and not care. But even that random auto-.sln file thing has disappeared in recent years and Visual Studio has learned more auto-workspace tricks from VS Code.)
I have started projects that just did that, started with a simple glob-only project and no prescribed file layout.
Yeah, dotnet doesn't let you micro-manage the linker specifically, but few languages since C++ do and arguably the C/C++ linker sometimes seems as much a bug of C/C++ as a feature in modern times.
.NET 4 doesn't exist and was avoided on purpose. There was a .NET Framework 4, but after Framework was abandonned in favour of Core they dropped the core suffix and skipped to 5.
Well, spiritually this is the 13th(?) major version of .NET (possibly more if we count Silverlight's runtime). You missed the part when there was .NET Core 1-3 alongside the old .NET Framework 4.8., and then they skipped Core 4 and stopped supporting Framework so they could finally fix their naming scheme.
I've upgraded apps from every version since .Net Core 2.0. The upgrades always take a few hours, maybe half a day (with the exception of 2.0 to 3.0 which took a few days - many breaking changes). It's well worth a few hours per year to get the advantages of newer languages features, enhancements in Asp.Net Core, security and performance enhancements in the .Net Runtime, etc.
Is upgrading every 3 years really that bad? As far as I know, they typically aren’t removing features or causing disruptive changes in .NET versions.
They did when switching away from .NET Framework, but this was because they had to reimplement many features from scratch to work on other platforms, and certain parts got left behind.
The last few .NET updates have been pretty much effortless updates for us. These are internal web apps and not using really esoteric C# features but that probably describes a reasonably large percentage of enterprise .NET adoption.
The only breaking change for us was how .NET 7 introduced [FromServices] which causes controller methods to use dependency injection for attributeless parameters. Confused me at first since it was a rather subtle update that didn't break anything until runtime.
A shift in those cultural dynamics is that you can ship the current .NET LTS with your app (or even STS if you feel like making that sort of security support SLA with your own clients). You aren't relying on their Windows Update habits (or lack of them) or having to install a big .NET installer that might break their other apps.
They may still get left behind on an older version of your software because they want to be, but their relationship to Windows is no longer the big excuse/reason to skip updating to your latest that it used to be.
You are right that it’s on a 2 year cycle. Though there is support for 3 years, so you could safely put off an upgrade for up to a year if there are breaking changes one release.
When I need to send someone an app, I usually use .NET Framework 4.8 because I know it's already installed on every recent version of Windows. This way all I have to distribute is a single very small exe. No need to package a framework with it.
Similar feat with .NET core usually results in a 70-80MB executable.
Yea that's why I write all my programs in C using the win32 APIs. It has a lifetime even longer than .NET Framework 4.8.1! I'll never have to change or adapt to new things. /s
reminder the .net compiler is IP of microsoft and they state this clearly when you invoke it on any platform other than windows. you are merging your company with microsoft and windows if you use it.
My favorite .NET 10 feature so far is not within the .NET library itself, but `dotnet tool exec` to run C# files as scripts without a build step. This has been available in F# for a long time via `dotnet fsi`, and for C# also via the third party cs-script tool. It took a surprisingly long time to officially reach the primary .NET language!
I only really wish C# would’ve been directly integrated as an alternative scripting language in PowerShell. You may balk at the idea for causing a ton of cruft for people who don’t need it; ”a whole new scripting language!” But the thing is — PowerShell already builds upon .NET so supporting a new language is a rather small effort (relatively speaking) if it happens to be a .NET language. And C# just feels so much better for me to code in when the scripts grow in size. I’m not sure I’ll ever become friends with the implicit returns. C# has become particularly suitable for scripting with the recent developments in the language: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals...
"dotnet tool exec" is not that feature; you're thinking of https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-... which they added to "dotnet run". "dotnet run my-cool-thing.cs"
"dotnet tool exec" is so you can run third party command line tools like csharpier that previously required "dotnet tool install" before you could use them. For example, in https://csharpier.com/docs/Installation you can now simply do "dotnet tool exec csharpier". This is like "npx" in the JavaScript world.
dotnet run *.cs is my favorite new feature for scripting. It has basically replaced powershell for me. It's trivial to script powerful operations now.
I guess LinqPad will lose some users to this feature.
This isn't LinqPad's selling point. All that dotnet run *.cs has done is remove the need to have a project file for each "script" you write.
LinqPad maybe has this feature but it's selling point is as a scratch pad to experiment with working with data and general futzing around.
The .NET team said they're working on VS Code integration. LinqPad still has some unique features (mostly database related), but at least for me, VS Code + dotnet run will be sufficient for my needs. Worst case, I can just throw a breakpoint on my database IQueryable result.
Ah yes, that's the one I was thinking of. Got confused by this article.
> I only really wish C# would’ve been directly integrated as an alternative scripting language in PowerShell.
You can embed C# in PowerShell scripts, and you have been able to do so for a long time. This webpage has a couple of examples of how this can work:
https://blog.nuvotex.de/run-c-inside-powershell/
That's not "embedding C#". That's runtime loading of .NET assemblies, which every .NET language--including PowerShell--can do.
One of many examples of C# following in F#'s footprints years later. F# deserves a higher profile in the .NET ecosystem.
F# has been a third class citizen for a long time... Last I heard the entire f# team was ~10 people. Pretty sure "find references" still doesn't work across c# and f# (if you call a c# method from f# or vise versa). That also means symbol renames don't work correctly.
I agree, but somewhat paradoxically, F#’s lack of new features kind of becomes a feature. Have you seen the number of C# features added in the last 5-10 years? It’s crazy
Half-baked adhoc features which didn't bring the language closer to Scala.
Still no HKTs and typeclasses, call-site expansion can only be simulated with partials and text-level code generation, etc, etc.
Not bringing the language closer to Scala is a feature, not a bug though.
Now I'm curious if C#/.Net 10 is smart enough to ignore the shebang line. Personally, I've tended to use Deno/TS for my more advanced shell scripting... the main runtime is a single executable that works fine in user context, and dependencies can be loaded/cached at first run.
Of course, with C# as a shell script, you'd likely be limited to just in the box libraries or have to setup a project for sake of running a script, like I've had to do with Node or Python stuff.
https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...
https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...
"dotnet run app.cs" natively supports shebang lines and nugets. The only requirement is to make sure the .net sdk is installed on your computer.
It's great that Microsoft added this as an official feature but there has been an open-source third-party solution that does exactly the same thing for a long time: https://github.com/dotnet-script/dotnet-script
I've wanted this for a long time. After reading this link, and the MS release announcement, I still don't understand what a "tool" is, or how you can use `tool exec` to run a single *.cs file. Is there a straight-forward recipe anywhere for doing this targeted at absolute simpletons?
Well if you're familiar with the node ecosystem it's a corollary for npx/bunx/etc.
It is so that folks can build and run "tools" that are executed, utilizing the nuget ecosystem.
Relevant links in the dotnet docs (was just a quick google away):
* https://learn.microsoft.com/en-us/dotnet/core/tools/global-t...
* https://learn.microsoft.com/en-us/dotnet/core/tools/global-t...
It's actually a top-level doc section in the primary dotnet docs (https://learn.microsoft.com/en-us/dotnet/).
To boil it down: you create a console app, add a couple of attributes to the solution file (https://learn.microsoft.com/en-us/dotnet/core/tools/global-t...). Packaging and publishing to nuget (if you want to share with others) is via `dotnet pack` and `dotnet nuget push` with some flags.
I do have to say it's actually very well documented.
Sorry for being unclear. Using tools isn't my goal. I want to run a single *.cs file from the console. It may be possible to achieve this using tools, but I don't know how. I did read the resources I could find, and didn't find any information about this.
Ah rereading your original comment that makes sense.
I found the announcement page here: https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...
And here are the docs for “dotnet run” https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-r...
You’re right that it’s missing this new functionality. The blog post has some details to get started, but I’m guessing that a docs link or section is missing for that.
Dotnet covers quite a bit so the docs are accordingly larger than other projects that have a smaller scope. I will say though that while hit or miss, on average I’ve enjoyed their docs more than the average project.
The docs are terrible right now (prerelease and all that), but to get started:
1. Install the dotnet sdk preview
2. Make a .CS file with top level statements.
3. dotnet run <file>
https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...
Sorry for confusing you. I can't edit the post now. The command is dotnet run script.cs. The tool stuff is about something else unrelated; NuGet installable CLI executables.
> I still don't understand what a "tool" is
"A .NET tool is a special NuGet package that contains a console application. You can install a tool..."
https://learn.microsoft.com/en-us/dotnet/core/tools/global-t...
it's actually very similar to the node.js / NPM equivalent, which came first:
https://docs.npmjs.com/downloading-and-installing-packages-g...
.NET was the most sane programming ecosystem that I worked in.
Great CLI, great package manager, very good stdlib, strong IDEs/Debuggers, etc.
but sadly interesting jobs like OSes, databases and compilers are way less common than in C++ world :(
I agree. The stability comes from its ecosystem though. Enterprise Software. Where things like meticulous use of Omit and Task are common place and really REALLY bad things happen if you fuck up.
But besides that, there’s a healthy gamedev community that embraced C# early and have been using it ever since. There’s C++ MFC guys that got duped into WPF and have been supporting it ever since. Winforms devs that are still trying to make a dark mode. I’ve even seen community grass roots “I need this in Silverlight” projects take hold and become one of the largest SDKs in the world. It’s cool. It’s fun. And with AOT, it’s everywhere. C# is like that cool uncle of your Father (Java) that likes to party all night but still holds a job. Maybe someday TS.Net will exist and we’ll all be singing “Back in my day”
I very much doubt about TS.Net, given the rewrite in Go decision.
.NET nowadays has a serious adoption problem, and they should spend more time talking with their own colleagues at Azure, about their use of Java, Go, Rust.
> .NET nowadays has a serious adoption problem
It's seriously going to make people question the future of the platform. Look at Microsoft's actions, not their words.
TS Compiler: Go New TUI Editor: Rust Winget: C++ (this would have been a great candidate for .NET)
At least PowerToys is C#.
.NET is great, but why isn't it good enough for Microsoft? The company that historically has had such a strong culture of dogfooding.
The issue was in the beginning they didn’t think interop with C/C++ was value add. People complained and they added “Managed C++” which unfortunately influenced C++03’s design a lot. It wasn’t until C++11 that Microsoft gave up. You couldn’t effectively interop with C++ without writing a managed C++ wrapper, which only worked on windows. They added support for P/Invoke to aid in Win32 calls (shell.dll, user32.dll) as a simple fix and we went nuts for it. Wrote wrappers using P/Invoke and a config map nightmare of which dll’s, or dylib’s, or so’s, you needed to get the form to show.
Fast forward to today… Rust can interop with C natively. Go can as well, though you’re bringing your luggage with you with CGO. .Net hasn’t ever really had that kind of focus. For one, IL, two, Microsoft saw the platform as a cash cow, three, ecosystem lock in allowed a thriving “MVP” contractor community.
You're clobbering together a bunch of different stuff and not making a ton of sense. C and C++ are very different languages, and that's especially true when doing interop with them from other languages.
For C-based libraries, P/invoking is trivial in C# and has been around forever. And it's cross-platform, working identically on Linux and macOS. I have no idea how you can say ".Net hasn’t ever really had that kind of focus" when it's been a core part of .NET from the start, and .NET relies on P/Invoke to do everything. Go look at all the DllImport() statements in the .NET reference source. Rust FFI is nearly identical in implementation to C#. Go has a slightly different implementation with the CGO module, but whatever, it's close enough. Just step back and remember that, in general, calling into C code is trivial in every language, since it has to be: all these languages will eventually have to hit libc / user32.dll / whatever.
C++ is a totally different story. You can't work with C++ libraries with P/Invoke, that's true... But you also can't work with C++ libraries using Rust or Go, either. Nor Python, Java, Javascript, or really any other popular cross-platform language.
C++ dynamic libraries are really challenging to call into for a variety of reasons. Virtual functions, multiple inheritance, RTTI, name-mangling, struct/class layout, vtable placement, ABI differences, runtimes, etc all make calling into precompiled C++ libraries a nightmare.
In fact, the only way I know of working with pre-compiled C++ libraries is with languages that target specific operating system / compiler collections. E.g., Objective-C++/Swift from Apple, and C++/CLI from Microsoft. These are obviously not cross-platform solutions, since they depend on knowing the exact compiler configuration used to build those libraries in the first place.
For every other language, you either need to manually build C shim libs that you can call into using the C-based approach above, or if you have access to the C++ source code, creating wrappers around it and building it into a module (for example, using pybind11 in Python).
The only reason is name mangling. You can disable this or export declspec it and keep the C-like signature. Painstakingly recreate the API in C#, using P/Invoke, and hope for the best. It wasn’t until late 2015 that we got codegen to “automate” this, or roll your own.
My perspective is from a first adopter, not an insider, 24 years ago, so I can’t speak to motive but as a customer, it felt exactly as I described. The documentation around P/Invoke was lax, you were shoved “Managed C++” down your throat by your rep, and any dream of going cross platform died in that meeting room until Miguel De Icaza did something about it.
It certainly is not, it is quite common to use templates directly or indirectly via the C++ standard library, and P/Invoke cannot handle those.
Also during .NET 1.0 days, Microsoft had a Website where you could paste any well known Win32 API or related SDK, and it would spit the annotations.
What was never as good in .NET as it was in VB 6 and still is in Delphi and C++ Builder to this day, was creating and consuming COM, which is kind of annonying given how much Windows team loves it.
At least it isn't as bad as the multiple reboots in C++, which I will keep asserting that from all of those, MFC still has the best tooling to handle COM.
You are jumping over a few facts there.
P/Invoke was born as J/Direct on J++, it became P/Invoke after the lawsuit, and Cool project turned into C#.
Managed C++ Extensions in .NET 1.0 got replaced by C++/CLI on .NET 2.0, it was a .NET Core 3.1 milestone to support it, and has recently been updated up to C++20, minus modules.
Still heavily used among .NET community on Windows.
Meanwhile the native C++/CX and C++/WinRT, both failed their adoption efforts.
I only wish if C++/CLI worked on other platforms...
Same here, for those of us comfortable on C++ land, it is much easier way to do integration with native libraries, than getting P/Invoke right.
My memory is fragmented in my older age.
Interestingly, the Rust windows crate is generated from an MSIL assembly. And same metadata might be used to generate C# bindings thanks to cswin32 [1] project. The meta-assembly generation (Win32 metadata project) is based on clangsharp and it's fairly straightforward to generate interop code for native Windows libraries. Some time ago I described this process on my blog for the detours library [2]
[1] https://github.com/microsoft/CsWin32
[2] https://lowleveldesign.org/2023/11/23/generating-c-bindings-...
The point is why is another language generating anything for C#?
Yes, and this approach is an extension of the one taken with WinRT metadata which is also ".NET assembly" based.
Windows and Office never adopted .NET for client code in the first place except for the Longhorn period in the mid-00s, which burned them and put them off it. If that didn't stop .NET in the two decades between then and now, I'm not sure why it would today. Actually, Windows is just now starting to adopt C# now that AOT is supported (I think the new native Copilot app is C#).
Many Windows Server admin tools (such as Server Manager or Virtual Machine Connection) and MMC snap-ins (e.g. Event Viewer, Hyper-V Manager) are written in .NET Framework 4. PowerShell is .NET Framework 4. Everyone’s favorite bloated IDE (Visual Studio) is .NET Framework 4 as well.
In the Office land, Excel’s Power Query is .NET Framework 4.
Adopting the modern .NET is probably harder due to its lifecycle.
Calculator is C# as well (though apparently that's somewhat recent: https://github.com/microsoft/calculator/pull/1598).
Porting to C# was a community effort after it went open source, it was originally C++/CX.
Powershell is .NET Core since version 6, the .NET Framework one is Powershell 5.1.
Yeah, Microsoft themselves have issue moving away from .NET Framework.
You can add SQL Server CLR, Dynamics, Sharepoint on prem, to the list.
OMG could you imagine writing MMC snap-ins using some sort of plugin declspec import bs in C++? .Net and reflection with Assembly.Load saves so much time and effort to build modular “ship it now, deliver features later, extend it if we fall behind” apps. Not that those are good things, it just means you can defer until your MS PM gets the budget to fill those backfill positions that have been open for 12 months because the hiring bar is astrophysics
I can, because due to Windows team love for COM and C++, many extension points require doing exactly that.
Want to extend the context menu actions, or add new thumbnail capabilities for a recent file format?
It is exactly that.
Even with WinRT Runtime Components, they were doing in a way that some APIs were only surfaced when using the components from C++.
Quite a different approach from OS / language teams at Apple and Google, where productivity with better languages has a priority no matter what.
Anders Hejlsberg, a main architect on C# & TS, stated somewhere that they re-wrote the TS Compiler in Go because the syntax was the closest to how it was originally written and allowed re-writing to be easiest. He has a great write up of it somewhere on GitHub.
Microsoft is an insanely huge company. There teams seem to be able to use whatever works best for the project/team.
The old XKCD comic of org charts in big tech shows Microsoft as a bunch of people aiming guns at each other for a reason. They'll have 5 teams making 5 competing products sometimes. That's the culture I'm aware of. I'm not aware of the dogfooding culture you are suggesting.
Yeah, and then at BUILD 2025 session, he ended up explaining how they had to rewrite all the data structures, due to the less capable type system from Go versus Typescript.
So the gain isn't as much as what is being sold.
Meanwhile Azure has no issues using AI based translation to port C++ projects into Rust, which they could have done in a similar way to port into C#.
Also, Go has a less capable tooling as C# for WebAssembly, due to Blazor efforts, the team has invested quite a lot into it.
It remains questionable what will they do for the in browser playgrounds and editors use cases.
Exactly. They chose Golang because they wanted to, not because of any technical limitation. Could have been C#, or Rust…
Not sure I agree on the adoption problem. A few medium sized client projects are nothing compared to the massive internal .NET codebases Microsoft has that run some of their largest services.
.NET team members have acknowledged this on podcast interviews, .NET Rocks, Nick Chapsas, The Unhadled Exception, among possibly others.
I would not touch C# unless you are already using it. Microsoft proves over and over it cannot be trusted in what they say. Watch what they do:
- basically dont use ant UI framework they say is the future and they are not using themselves - be vary of the future of some of it stuff like C#
C# has been around a long enough time and Microsoft's teams over that time have done a pretty good job making upgrading each version easy.
As long as the current leadership in the C# & .NET teams remain, it's a very safe language and framework to use. They also deserve huge kudos to API & performance improvements the past decade since moving on from .NET Framework 4.x, which still runs fine.
They also have a lot of internal & external users using it.
Oh I learned this the hard way. Managed DirectX, XNA, Creators Club, Windows Store, shared profit motive, fair business practices, Project Natal/Kinect, Azure, and finally… .Net. Yup, Microsoft loves developers… loves their subscriptions.
I know, so sad, could have been a great opportunity.
Just like every CNCF project that Azure contributes to, written in Go or Rust, which could have been great carrots to further .NET's adoption.
I blame historic microsoft for their anti-oss stance. It kneecapped the .net ecosystem for over a decade and created an attitude of "if it isn't in .NET, I won't use it".
That has certainly played a role, however that is common to Windows development culture in general.
The 3x "Developers !" meme isn't for nothing, Microsoft just like Apple (and NeXT), always a full stack development experience story.
Everything that one needs is there on the full Visual Studio Professional, and then there was the ecosystem of small indie developers and MS Partners building on top of that.
That is quite different from UNIX FOSS culture, and has also been a friction point to those that went Apple without understanding that also have that on their DNA, regardless of OS X foundations.
I agree as well. The hostile attitude towards OSS under Ballmer led to this. Nadella had the correct approach and a year later, started repairing those bridges, joining the Linux Foundation.
Many things under Satya also feel like good old Microsoft, like lack of GUI frameworks for GNU/Linux, killing VS4Mac after the rewrite, dotnet watch drama, profiling tools being VS only,...
MAUI not supporting Linux feels like such a huge whiff. It is clearly possible to get at least decent cross platform support that includes linux in .net considering Avalonia exists.
MAUI is supposed to use native ui components, AvaloniaUI just uses Skia. I think going with a non-native approach would kinda make Linux a clear second class platform, especially with all the native features that need to be rebuilt?
Is there any multiplatform ui framework that's actually "native" for all the different linux ui toolkits?
VS4Mac deserved to die, that was Mono Code aka Xamarin and it was terrible. No offense to Miguel, mono is amazing, but the IDE they made was horrid.
Microsoft was asleep at the wheel the last decade of Ballmer, leaning too heavily on their Xbox Studios and Enterprise Cloud to care about desktops. They gladly let Mac take office share as “no enterprise software developer would ever choose a Mac”. Those famous Mac vs PC ads.
The GUI development story has plagued us for a long time. No one wants to take on the challenge of a unified user interface spec. Why? Because it will always be wrong - ever changing - and a giant suck of corporate resources.
It’s better to let each team think of their own way of doing things. Then, they can choose the best of them and release them as frameworks (WPF) only to be abandoned by the next regime change.
MAUI, UWA, Metro, WPF, all an attempt to save what effort they have made. Ultimately, everyone loves their Electron apps, so HTML has become to new UI paradigm. They move too slowly. Convinced “they know better than you” and will spend the next 5 years hyping up the next XML abomination.
No it wasn't any longer, that is why the rewrite took place.
I rather use XAML, if given the choice.
What's Omit refer to in this context?
The 14,000~ instances of T? or _
Since you mention great CLI - is there a CLI tool that is free/cross platform that works like prettier ? I found https://csharpier.com/ but have never heard of anyone using it.
Also not sure how it works with linters like roslynator or stylecop ?
This is something I miss very much when coming back from TS, other languages also have better formatters. C# is very tied to editors/IDEs which is a nightmare in teams where some people use vs/vs code/rider
Csharpier is the best option available. I've been using it for 3-4 years now and had success getting it adopted at my last two companies on greenfield projects. It's not exactly an unknown tool - nearly 2k stars on Github. But a lot old school .Net companies just don't seem to have much interest in auto formatters because they've been working without them for a long time.
If you're using csharpier you don't need to use Roslynator formatters. No issue with the analyzers package. The csharpier docs have info on what StyleCop rules need to be adjusted so they can work together. Personally I don't use StyleCop anymore as it seems to be fairly dead, and I don't really feel the need for things like enforcing file layout or naming.
Edit: Also I will add that unless the landscape has changed recently, I believe csharpier is the only C# tool that has deterministic formatting good enough to enforce code formatting checks in CI.
dotnet format [0] exists and is maintained by the .NET team. It is different from Prettier in that it is much more configurable, but it gets the job done for us. It does integrate language services and can automatically apply code fixes for custom analyzers. I have not explicitly tried roslynator or stylecop, but I suspect this would work as expected.
[0] https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-f...
The problem is that dotnet format is horribly slow. So much so that it's only useful as a precommit hook
I was not able to use (recent) dotnet-format as standalone .exe tool, also it only worked if inside an actual project with .sln/.slnx file and all that. I could not instruct it to work on single file.
> It is different from Prettier in that it is much more configurable
I only tried it briefly but found it was waaay to lenient with the amount of variance in style it left unchanged (eg line breaks for function parameters) - can it get configured to produce consistent formatting like prettier ?
I think there are also a lot of default rules which aren't enforced until they're bumped up in severity in the .editorconfig.
Also it can hook into roslyn analyzers, so if you want a more opinionated analyzer then stylecop analyzers ( https://github.com/DotNetAnalyzers/StyleCopAnalyzers) would be an option, although I haven't used it myself for a long time.
It can be configured to be much more aggressive with formatting, but I'm not certain if you can force it to produce the exact same output for any possible whitespace in the input.
Hi! I use csharpier, it does the job - I included it as a preliminary check in our CI pipeline for a step of merge requests quality assessment. It is the closest tool I found, that ressembles prettier. You should definitely give it a try.
I’ve been using csharpier for almost a year now and it’s amazing. Because it’s opinionated, you don’t have the space to overthink it, you just use it.
Besides, I really like its formatting style.
csharpier is great. It is what "dotnet format" should be.
On my little enterprise bubble, the only place remaining for C and C++ is writing native libraries to be consumed by managed languages, or bindings.
The last time I wrote pure C++ applications at work, was in 2005.
Libraries still regularly.
For the last few years, I’ve been developing CAM/CAE software on my job, sometimes embedded Linux.
Same experience: last time I developed software written entirely in C++ was in 2008. Nowadays, only using C++ for DLLs consumed by C#, for 2 reasons: manually vectorized SIMD for CPU bound numerical stuff, and consuming C or C++ libraries like GPU APIs, MS Media Foundation, or Eigen.
Sometimes I feel like there ought to be a Hacker News like forum for us dinosaurs stuck in the Enterprise tarpit. Instead of talking about Elixir and AWS startup credits, we’d complain about the weather and legacy CORBA components.
Indeed, it could be interesting.
What do you mean by CORBA, isn't that the cool new shiny WebAssembly components? :)
I've been using it since 2002 so you can imagine my opinion when jumping to other languages. They've been very good to steal all of the things that worked from other languages and constantly iterate on their core infrastructure and language.
Do you know about any sizeable open source projects written in C#, other than what Microsoft has produced? I rarely come across anything written in it.
It's a curious thing, the .NET ecosystem. The overwhelming majority of it's ecosystem seems to be dominated by Microsoft first-party libraries and frameworks. 3rd party libraries and frameworks seem to either get swallowed up by Microsoft, killed, or never reach critical-mass.
Often in the .NET ecosystem, it seems there is exactly one library or framework for thing $X or $Y. Whereas in the JVM ecosystem, you have 30+ logging libraries, 87 different MVC frameworks, etc. (yes, I'm being a bit facetious, but you get the point).
I imagine .NET developers often think this is a good thing, in regard to their ecosystem. No guessing what to use, just go with the "blessed" path and don't think about it. And, to that end, there is some obvious merit to this.
However, I feel the .NET ecosystem loses out on cross-pollination of ideas. There's zero possibility Microsoft's employees just happen to make the best frameworks and libraries... there should be many web frameworks - each competing for mindshare and trying to out-innovate each other, each with their own pro's and con's, etc.
So, while .NET might be technically open source, it still feels rather like a closed source ecosystem, controlled by a single corporate entity.
That because that's the environment MS nurtured for over a decade. They were openly hostile to things like nuget up until like 2016 or so.
They purposefully made it painful to venture out of the MS ecosystem.
There are several logging libraries for .net as well, microsoft even lists them: https://learn.microsoft.com/en-us/dotnet/core/extensions/log...
Libraries getting swallowed up is not so bad as it sounds. For instance for web frameworks there was a phase of experimentation with projects like Nancy that inspired changes for asp.net core. There is still alternatives like fast endpoints.
Also you have things happening like integrated system.text.json replacing newtonsoft.json that over time took on some cruft.
Why would anyone make a .NET open source library when Microsoft is quick to squash anything that is actually useful with their own open source implementation?
Microsoft still has some lessons to learn about fostering an active open source ecosystem -- of course, unless they are intentionally suppressing it in .NET.
It's weird you using logging as there used to be 3/4 different libraries people used (nlog, log4net, elmah, another one I forget?).
Then serilog came out and pretty much everyone switched to that in a very short period.
https://github.com/MonoGame/MonoGame (runs even on consoles, which is rare for open source game frameworks and engines)
https://github.com/SubtitleEdit/subtitleedit
https://github.com/jellyfin/jellyfin
https://github.com/AvaloniaUI/Avalonia
https://github.com/bitwarden/server
https://github.com/unoplatform/uno
https://github.com/files-community/Files
https://github.com/NickeManarin/ScreenToGif
https://github.com/DevToys-app/DevToys
https://github.com/d2phap/ImageGlass
https://github.com/ShareX/ShareX
https://github.com/duplicati/duplicati
https://github.com/OpenRA/OpenRA
https://en.wikipedia.org/wiki/Ryujinx
https://sourceforge.net/projects/keepass/
https://github.com/orchardcms
https://github.com/piranhacms/piranha.core
https://github.com/umbraco/Umbraco-CMS
https://github.com/quozd/awesome-dotnet
The FFXIV extension/mod tool is a fun example.
https://github.com/goatcorp/Dalamud
https://github.com/SM64-TAS-ABC/STROOP
Can't speak for FLOSS, but I've worked on massive projects in various Banking, Govt and eLearning spaces. I've never really hurt for library support via NuGet either. It's honestly not always my first choice, but pays the bills.
I mostly just dislike a lot of the excessive use of "Enterprise Patterns" for projects that don't come close to actually needing them.
It is a self-fullfilling prophecy: No big open source without motivated contributors, no contributors because of bad rap because of no big open source projects.
It is not technology what holds .NET back. It is also not politics (nearly all languages have evil overlords). It is people who hold up to statements like: "I will not touch .NET with a 10-stick-pole"
Ryujinx, a state-of-the-art Switch 1 emulator, was open source and written in C#
Not sure what your definition of sizable is. But if it’s just physical size of repo then my language-ext project [1] is about half a million lines of code, ~7,000 stars, and ~25 million downloads.
We are out there :)
[1] https://github.com/louthy/language-ext
Jellyfin / Emby
A lot of the *arr tools like Sonarr
Bitwarden and Keepass
Kavita (self hosting for books/comics)
https://github.com/paintdotnet was the first one that came to mind.
Akka.NET and AvaloniaUI are two big ones.
I'll add Orchard CMS to this list. Also a lot of the seven seas software.
Bitwarden
Unity?
Is Unity open source?
I liked .NET but the performance was really bad for anything that had even reasonably latency requirements. But this was 15 years ago, so maybe it has improved. I don't remember exactly what I wanted to do but it was something like pumping some event every few milliseconds and it was basically impossible. The jitter was already larger than the interval.
https://medium.com/@ocoanet/improving-net-disruptor-performa...
I despise working with Nuget. Whether it's a restore, managing your csproj, or publishing packages, compared to NPM it's an absolute mess.
It is the first time I see anyone praising npm.
> .NET was the most sane programming ecosystem that I worked in.
Having written libraries in .Net I fully disagree with that notion.
First insanity is figuring out what in the fuck you need to support. .Net framework or .Net standard or .Net Core or Mono (or .Net Duplo or .Net dot nes :P).
Second is the Source generators. I swear using t4 templates is the saner option. I've had cached artifacts appearing out of the fucking nowhere like unkillable zombies despite closing the Rider, clearing its cache, and killing build server.
Third is the availability of packages. In Rust and Java there are like several libs for anything (even if C bindings).
> First insanity is figuring out what in the fuck you need to support.
Since I no longer support .NET Framework, it's just .NET now.
.NET was two platforms for a while and they did a lot of weird stuff to make that work (.NET standard) but it's been one platform for many versions now so that specific difficulty can mostly be ignored.
Easy to say, but it poiets to ecosystem fracture. But I've been getting requests to support really weird and outlandish versions. Stuff like Mono and .Net 4.56
Most C# libraries I use are outdated, crappy and do just a little less than what I need. Also, most Rust libraries I try to use are outdated, crappy and do just a little less than what I need. Maybe what I need is niche but my experience is pretty similar in that regard.
All I want is for dotnet watch to behave in a predictable way. In .NET 9, even when using —no-hot-reload, sometimes CSS changes to components are not picked up on Blazor components.
It’s so aggravating because ASP.NET with server side Blazor components really has it all: type safety, server-side components ala Astro, fantastic ORM model, great runtime perf. But this little issue makes dev quite tedious at present: did I mistype a Tailwind class name, or did dotnet watch miss the change?
I inherited an MVC app that has a bunch of jQuery rendering crap and I would like to move to server side components - since you seem to be into Blazor Server side - have you heard of HTMX ?
What would you say would be the benefit of Blazor vs HTMX and Razor Pages for subviews ?
My experience with Microsoft UI toolkits after winforms, is that they are all janky over-engineered stuff (Silverlight/WPF/Xamarin/Maui) terrible tooling and support compared to alternatives. And Blazor using websockets makes me believe it is the same. The compile to WASM idea is a typical example of this.
So what would be the selling point of Blazor ? It feels like you are just bundling stuff into Blazor magic when you could KISS with something simple like HTMX ?
I still haven't found a use-case for the websocket Blazor Hybrid and it still smells so much like the worst mistakes of the original ASP (before .NET) and the `runat="client"` versus `runat="server"` confusions.
Blazor WASM makes some sense if Silverlight ever made sense for a project: it's a way to ship C# directly to the browser for maximal code sharing with other C# projects in a C# ecosystem. It's basically "what if Angular/React was just Razor Pages running on the browser?"
It's absolutely the opposite of KISS, it's lifting and shifting the entire .NET runtime in WASM to the client. Outside of corporate networks and packaged apps like Electron or Tauri, I'm not sure it makes any sense. But if you like writing Razor Pages and wished they ran closer to the client metal, and you can afford the bandwidth of an entire .NET application soup-to-nuts as your SPA framework, there is a sense to it.
If all you think you need is Razor Pages with HTMX that's probably all you need.
>I still haven't found a use-case for the websocket Blazor Hybrid and it still smells so much like the worst mistakes of the original ASP (before .NET) and the `runat="client"` versus `runat="server"` confusions.
That is exactly my read of it, especially given Microsoft track record on delivering with stuff like this.
Not sure about the Silverlight comparison - in the days of Flash, browsers did not even have a way to stream video reliably, nowadays it just cramming a square peg in to a round hole - heavyweight runtime built on multithreading crammed to a single threaded event loop. I have not tried it - but after using .net in much more powerful/native envs like Android - I know for a fact that the iteration/build/debugging story sucks compared to native JS/TS. Also as bad JS is, TS makes it saner, tooling has matured and DOM APIs are built for JS.
> nowadays it just cramming a square peg in to a round hole - heavyweight runtime built on multithreading crammed to a single threaded event loop
Sometimes the "event loop" part is forgotten because JS' single threaded thing is very "cooperatively threaded". This is a large part of why async/await works so well in JS and is growing so quickly in adoptions. .NET's multithreading is built in a way to excel in "cooperatively threaded" environments (its task pools are cooperative by default, for instance, and also arguably heavy use of async/await was C#'s idea first).
It would be great to see more WASM multithreading powers, but writing C# for today's WASM environment doesn't feel that different from "regular" multi-threaded C#.
> I know for a fact that the iteration/build/debugging story sucks compared to native JS/TS
WASM debugging is nearly great, including growing Sourcemap support. The ability for Visual Studio to be the Debugger interface to Chromium-based browsers is more powerful that ever. Certainly in its debugging story Blazor WASM is much advanced from Silverlight which was only really debuggable in IE and then was still often flaky.
> DOM APIs are built for JS
There's still talk of making more direct DOM APIs for WASM. Might be interesting to see eventually.
This is why it is so easy to relate Blazor WASM to React. Blazor is essentially using Razor templates to define a Virtual DOM which it then sends render updates across the WASM/JS boundary to a very tiny virtual DOM renderer.
It's not what I'd use for smarter direct DOM work, but in comparison to React it gets the job done and works surprisingly well, even with the language barrier and data marshalling across sandbox layers.
I've used Blazor WASM on Enterprise projects. I'd probably use it again on Enterprise projects. It can be real nice to have backend and frontend all entirely in C#. (In different projects. So that you can scale them independently if nothing else.)
As of today (and going forward), there are two different flavors of Blazor server-side rendering. There is the original version where the component is rendered on the server and interactivity is provided via websockets. Now there is also static server-side rendering, which works very similarly to razor pages, pages/components are rendered on the server and there is no interactivity. You can then, of course, add interactivity wherever you'd need it with server-interactive or webassembly interactive sub-components.
I wouldn't necessarily say there's any benefit of Blazor over HTMX, it just depends on what you're most comfortable with and what works for you in your project. But you could architect your front-end in a similar way where you have small blazor components in your pages with interactivity.
I think Blazor is in a nice state now, where I can iterate very quickly on projects with just static server side rendering and add interactivity whenever it's needed. It gives me a very fast website, rendered on the server, and the option to add some interactivity whenever I need.
Blazor static server side + HTMX is probably the only way to make a cost efficient and performant version of Blazor suitable for public websites. WASM is way too big and slow, Websockets take up server resources and cause problems with timeouts where the user has to refresh their screen losing all state.
What would be the benefit over Razor pages tho ? Component model ? Feels like partial views and razor templates might not be the cleanest/dry-est solution but would make the implementation super straightforawd.
Yeah there is basically no real difference between MVC or RazorPages or BlazorStaticServer pick your poison depending on your preference. Personally I wish the .NET team would just add components to MVC and RazorPages then we can forget about Blazor.
Jetbrains built some awesome tooling to support HTMX apps using razor engine and some MVC conventions. It's pretty neat.
https://www.youtube.com/watch?v=uS6m37jhdqM&t=1800s
> It’s so aggravating because ASP.NET with server side Blazor components really has it all
Agreed. I bailed on Blazor over the tooling experience. Editing components in VS2022 was so janky for me. Syntax highlighting and intellisense never worked correctly.
I don’t think there’s ever been any good tooling for the entire collection of ASP.NET DSLs. Be that MVC, Razor, or Blazor. Genuinely the same problems I had in VS2010 still happen in VS2022.
There’s been some changes and improvements, but I really have to ask what the editor tooling team within that team are doing.
I know there are some very difficult problems involved in parsing and formatting and highlighting bastardised mixtures of HTML, C#, and JavaScript all in the same file but if anything I think that perhaps suggests it was a bad idea to begin with.
Consider the tooling for desktop and mobile apps with XAML (WPF, Avalonia) or even WinForms - they all have code behind support.
Meaning there is no need (or ability) to mix all three in the same file.
We have had great success with Maui Blazor Hybrid. Each release hot reload gets better with fewer edge cases. I also found that having a separate .cs file instead of in one file helps with highlighing and intellisense.
I hear a lot of complaints about dotnet watch, but my experience doesn't match. I just use it from the terminal (instead of running it from an IDE) and it mostly just works.
Are you using Visual Studio or another tool (vscode, vim, rider)? I found hot reload works a lot better in Visual Studio than any other IDE
That's true, but even in Visual Studio, Hot Reload breaks too often to be comfortable. It seems the intermediate .g.cs handling is a bit error prone.
Rider, but I'm on Mac, so I can't use the real VS. I run dotnet watch from a terminal separately.
Might be worth viewing the full list of changes in the blog post that the article links to:
https://devblogs.microsoft.com/dotnet/dotnet-10-preview-6/
Also, if you want to see the full list of changes in .NET 10 (not just the latest preview), you can find it here:
https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotn...
All these changes, yet still no satisfactory UI framework.
Still no migration path from WinForms to something modern.
I love .NET but if you're taking on an older desktop app that is still using VB.NET and WinForms it feels like Microsoft have decided to let you circle the drain with no supported way forward into MAUI or whatever stupid XAML UI they decided is the solution these days.
On a server, .NET is fantastic and it's entirely possible to build and debug your system on Linux with no loss of productivity, but the desktop stuff is bad and getting worse.
I've tried each iteration of UI paradigm they've tried since WinRT and never really had any significant problems with any of them. WinRT, UWP, WinUI, MAUI...
But then they aren't even willing to invest the time to dogfood their own products and fully replace the windows UI. Really doesn't inspire confidence.
I suspect they also made a bad bet by going so hard on blazor without putting more support behind WASM itself. Now that's stalled out with WASM's own failure to reach critical mass.
Microsoft has zero vision in the UI space. It’s crazy that there isn’t there a single, obvious solution for developing Windows applications in 2025.
I agree that it seems they’ve made some bad bets and now are bogged down supporting half a dozen different frameworks with different limitations and tradeoffs.
They keep trying to reinvent the wheel, but it doesn’t seem like they’ve ever really meaningfully improved on WPF.
At least there is Avalonia for an open source, cross platform WPF alternative. It seems like the sanest way of making desktop applications with C# currently.
That would be a first, not having significant problems.
As someone that was deeply invested into WinRT since Windows 8, and went back into distributed systems and Web after all the disappointment regarding how managemetn handled it.
Everyone on the Windows development ecosystem has had enough from the multiple reboots and tool changes, UWP never being as good as WPF, WinUI iterations even worse, the team now went radio silent, the last community call was a disaster,...
Sorry, to be clear I meant no significant problems with the tech.
Sure, it was opinionated tech, but that would’ve been ok if they had stuck with it like C# itself and fleshed it out more, which only would’ve happened had they implemented the entire OS in it. The fact that they couldn’t is in my mind the exact reason the tech failed.
I agree with your point of view, this was the second coming of Longhorn, WinRT was after all pushed by the same folks that killed the Longhorn effort, those on Windows team that sided with Steven Sinofsky, using COM in Vista as future foundation for .NET ideas in Longhorn.
The Hilo tutorial for Windows 7 remarks regarding C++ are quite telling of their point of view, on which programming language one should be using,
https://devblogs.microsoft.com/cppblog/announcing-hilo/
"The rich user experience of Windows 7 is best accessed through a powerful, flexible language, and that means C++: by using C++ you can access the raw power of the APIs for Windows 7."
From https://learn.microsoft.com/en-us/previous-versions/msdn10/f...
Joe Duffy has some remarks on how even with Midori running Asia Bing infrastructure, and proving workloads in front of the Windows team, the reception to it was rather cold.
https://youtu.be/CuD7SCqHB7k?t=921&si=r8a0nScB4fcrxxIu
Eventually he left MSR and created Pulumin on top of Go.
Meanwhile Apple/NeXT and Google, decided to push languages like Objective-C, Swift, Java, Kotlin, over classical C and C++, proving the point that change is possible if management is willing to support the team, even if that is a very long run.
See Apple's Metal Swift bindings, versus Microsoft's Agility SDK for DirectX.
Assuming the web is not an option for whatever reason.
I did some Win32 interop recently and found it to be refreshing. It's definitely lower level and more difficult, but it will outlive all of these other paths.
Using tools like cswin32 makes this a lot more tolerable development experience from managed code.
Only thing I want to hear about lately is the next major version of Visual Studio, I feel like it will never come. I always feel like every major version has drastic improvements, and I'm starved for them.
They’re consolidating the tech with SQL Server Management Studio, last I heard. I think they mean to get the rewrite of SSMS out this fall, but I may be misremembering. A new major version of VS is probably coming, although I must say I’m pretty pleased with the current tranquility.
This thing has barely changed in the ~30 years I've been using it. There's definitely room for some more improvements.
You can divide visual studio into 4 era's. The vs6 (we smashed all of our dev tooling together and its integrated decently) era, the vs2002/vs2003/vs2005 (we broke it all and you will like it and never speak of C++ again), vs2010 era (we fixed all of that from 2002 sorry about that), vs2017/vs2022 (it updates from the internet and takes forever to install and now does everything).
The problem is MS is unwilling to stick with anything dev wise. The whole ecos system is a littered realm of half forgotten techs that may or may not be supported anymore. Wrapped with very confusing messaging to the devs what to use.
I prefer VS Code... though MS has for better or worse kept the .Net tooling relatively weak. I'll use Rider or VS on a few occasions... then retreat back to Code as much as I can.
For split web projects, definitely work on the web ui in VS Code.
I used to like VS Code, but something about it changed and it does not feel as snappy as it once did for me. Now I prefer Zed.
Electron apps are seldom snappy, we use it, because some plugins aren't available anywhere else.
VS2017 was the introduction of the modern VS installer that is way faster than the prior ones.
Also (since 2015) forward/backward (to a degree) CRT compatibility.
https://learn.microsoft.com/en-us/cpp/porting/binary-compat-...
This saved so much time, space and support - where previously we had to recompile stuff, and if you had Maya/MotionBuilder/etc plugin it had to use the right compiler.
Also now even with newer IDE you can instruct the project to use older (or even better - a specific) version of the toolchain.
I dunno, I think the big change over to roslyn in 2015 was a bit of a tectonic shift.
My guess is we'll know soon. Maybe at VS Live next week?
> "Stay tuned for more details later this summer about what's coming next for Visual Studio..."
https://learn.microsoft.com/en-us/visualstudio/releases/2022...
Just buy a Rider license. Never looked back.
Maybe they will use this chance to finally switch it away from the .NET Framework to the modern dotnet runtime with its many years optimizations.
Have you tried Rider?
Yes, it was a bit rough originally, but they've managed to make it better, sadly some employers do not want to buy into JetBrains.
They should fix github issues and write in-depth tutorials, instead of AI features or minimal API.
I adore minimal API and when paired with Carter it’s just gorgeous.
https://github.com/CarterCommunity/Carter
My current absolute favorite is .NET Aspire. Build distributed applications with an OTEL support dashboard - up and running in minutes.
https://learn.microsoft.com/en-gb/dotnet/aspire/whats-new/do...
Only gap in Aspire is deployment (k8s) tooling which is on the way.
"they" are more than one person and can do more than one thing at a time
Looking forward to playing with 'dotnet run app.cs' instead of PowerShell.
It'll probably not be really useful until multiple files support arrives in .NET 11: https://github.com/dotnet/sdk/issues/48174
One-shot execution looks exciting, what problems does it solve? Less cluttering in the environment?
Scripting, CLI tools ...
It also solves a more subtle problem - when people install a tool globally they install latest _at that time_. But the world doesn't stand still, and things get updated. `dnx` always uses the latest available version by default (you can of course pin with `dnx <package>@<version>`) so that you never get out of date.
I haven't used C#/.NET since .NET 4 - I remember it was great, yet heavily tied into Visual Studio, and forget about using CLI for things like most other languages. It was all GUI or nothing. Insurmountable XML files.
How are things these days with .NET 10! Jesus, 10!
Dudes who use it daily, what is your favorite feature you think?
Favorite recent language feature is a big investment in C# pattern matching. It's a big feature from the functional programming world rare to see in "Enterprise" languages.
Favorite recent runtime feature is all the cool low level stuff opened up by Span<T> (and Memory<T>). It has a similarity to Rust borrowing, but well integrated into the CLR's existing type system. It has opened all sorts of performance code possibilities that is still memory-safe/type-safe with fewer needs for falling back to "unsafe" operations. This is not just exciting because it is an interesting playground if you like low-level programming, but also because it has been a performance flood lifting all boats in the .NET ecosystem. A lot of code over the last few years has gotten easy performance boosts by just recompiling (because the compilers were taught to prefer Span/Memory overloads when they get added; no change to C# or F# code, just the compiler picking a new performance path).
Definitely change for F# code, some of those Span overloads broke type inference. Also, certain APIs even removed their non-Span overloads between .NET versions, which was a straight up breaking change for every language other than C#.
The biggest change for me has been the ability to deploy my web sites to a Linux box instead of having to deal with IIS.
WinForms app development hasn't changed one bit in 25 years.
If you code in C# then they've added some nice new language features every year to make your code a little tidier.
And the whole framework is totally open source now, which is a bonus.
There's nothing I'm really asking for. It does pretty much everything I need these days.
Very different. That was the .NET I knew in college, .NET Core really changed the game. I personally use CLI just for EF Core (ORM) but Rider support is there so you're not tied to VS.
My fav feature is honestly how little boilerplate I need compared to Spring Boot and the syntax sugar is honestly really nice.
My favorite feature, especially considering the past of "heavily tied into Visual Studio" is the platform independent nature of (most of) "modern" dotnet. That is to say, I run Fedora on my laptop, and I do not want Windows, yet I don't feel like a second class citizen and dotnet runs well and is available from repositories that Microsoft provides for various Linux distributions (it just hit me how strange this is, for _Microsoft_ to offer official repositories for Linux operating systems...).
I also really like that its development is fairly open (it's on github). From a more technical point of view, I think C# is a slightly better Java. A pretty nice language overall. It's not gui-or-nothing with dotnet core so it's not too difficult to create workflows for ci/cd pipelines, although the .net framework solutions we still have aren't too much harder to script: msbuild is pretty capable.
The version numbers used to increase much more slowly. Since the .NET (modernized / cross platform) core "track" the version number increments every year.
The version increments roughly every 6 months. It's almost the exact same update cadence as NodeJS: LTS versions are even numbers released in the Fall and STS versions are odd numbers released in the Spring. STS often focuses on "bleeding edge features" and LTS often on performance and stability. (Though both are year round projects and there are bleeding edge features in an LTS and perf/stability fixes in an STS.)
https://learn.microsoft.com/en-us/lifecycle/products/microso...
The last 5 version have been released a year apart, in Novembers.
It's still stuck in weird formats and monoliths. A lot of GUI-only stuff has been ported to the mega CLI, but it's still the weird Visual Studio format plus XML files that you cannot replace with a simple Makefile. You still can't just compile a bit of C# as-is, it must have the Solution, Project, Assembly etc. chain, the run-as-script feature is nice (lots of cheers when that was presented! even on the live stream), but it's specifically not designed to allow you to assemble a toolchain that works for what you need. There is only one and it has everything, no options.
The question, of course, becomes: when does that matter? For a lot of people who are in to .NET, they see that as a benefit. Look at Go through this lens, and it's similar; the go CLI is the compiler, linker, package manager etc. I suppose the biggest difference is that it doesn't prescribe solutions and projects and file formats to go with them, which enables you to put this in any existing CI, make or other system.
> it's still the weird Visual Studio format
.NET 9 (and VS2022) added support for the SLNX replacement format to replace the old weird solution format:
https://devblogs.microsoft.com/visualstudio/new-simpler-solu...
Yep, but you still can't say "compile and link everything in this tree". Technically, the language can, but the framework assumes specific compiler, linker and layouts on the filesystem so at that point you can't. It really wants that editor-related stuff to be part of the framework, and everything else has to bend for it.
A Project file today can just be a full tree glob. New projects start out in that form. The `dotnet` CLI is still going to assume some default output paths as it builds object files and executable assets, but those are all easily flag configurable today. (I've done some wild CI things.)
You don't have to use a Solution at all with the CLI, you can do everything in a single Project and one full tree glob. (Technically you haven't need a Solution with Visual Studio for a long while either, if you don't mind it sometimes auto-creating them at compile time, and even then you can just .gitignore .sln and not care. But even that random auto-.sln file thing has disappeared in recent years and Visual Studio has learned more auto-workspace tricks from VS Code.)
I have started projects that just did that, started with a simple glob-only project and no prescribed file layout.
Yeah, dotnet doesn't let you micro-manage the linker specifically, but few languages since C++ do and arguably the C/C++ linker sometimes seems as much a bug of C/C++ as a feature in modern times.
.NET 4 doesn't exist and was avoided on purpose. There was a .NET Framework 4, but after Framework was abandonned in favour of Core they dropped the core suffix and skipped to 5.
> NET 10! Jesus, 10!
Well, spiritually this is the 13th(?) major version of .NET (possibly more if we count Silverlight's runtime). You missed the part when there was .NET Core 1-3 alongside the old .NET Framework 4.8., and then they skipped Core 4 and stopped supporting Framework so they could finally fix their naming scheme.
I prefer .Net Framework 4.8 Longer lifetime than any .Net version.
I've upgraded apps from every version since .Net Core 2.0. The upgrades always take a few hours, maybe half a day (with the exception of 2.0 to 3.0 which took a few days - many breaking changes). It's well worth a few hours per year to get the advantages of newer languages features, enhancements in Asp.Net Core, security and performance enhancements in the .Net Runtime, etc.
Is upgrading every 3 years really that bad? As far as I know, they typically aren’t removing features or causing disruptive changes in .NET versions.
They did when switching away from .NET Framework, but this was because they had to reimplement many features from scratch to work on other platforms, and certain parts got left behind.
The last few .NET updates have been pretty much effortless updates for us. These are internal web apps and not using really esoteric C# features but that probably describes a reasonably large percentage of enterprise .NET adoption.
I don't think they introduced any breaking changes after .NET 6
Every version had breaking changes, they could not affect you too much though: https://learn.microsoft.com/en-us/dotnet/core/compatibility/...
The only breaking change for us was how .NET 7 introduced [FromServices] which causes controller methods to use dependency injection for attributeless parameters. Confused me at first since it was a rather subtle update that didn't break anything until runtime.
.NET LTS is on a 2-year cycle, isn't it?
I've worked in .NET shops with very niche WPF/WinForms applications where customers were years behind with our software/major .NET Framework releases.
I don't think it's a technical challenge, more a cultural one.
A shift in those cultural dynamics is that you can ship the current .NET LTS with your app (or even STS if you feel like making that sort of security support SLA with your own clients). You aren't relying on their Windows Update habits (or lack of them) or having to install a big .NET installer that might break their other apps.
They may still get left behind on an older version of your software because they want to be, but their relationship to Windows is no longer the big excuse/reason to skip updating to your latest that it used to be.
You are right that it’s on a 2 year cycle. Though there is support for 3 years, so you could safely put off an upgrade for up to a year if there are breaking changes one release.
With all the dependencies that maybe getting an update to the new .Net version, yes.
When I need to send someone an app, I usually use .NET Framework 4.8 because I know it's already installed on every recent version of Windows. This way all I have to distribute is a single very small exe. No need to package a framework with it.
Similar feat with .NET core usually results in a 70-80MB executable.
Is 70-80MB really a big deal to distribute in 2025?
Also if you use trim unused code and compress the executable in my experience it's usually a lot smaller than this.
Yea that's why I write all my programs in C using the win32 APIs. It has a lifetime even longer than .NET Framework 4.8.1! I'll never have to change or adapt to new things. /s
I change things if it’s necessary, not for the sake of using the newest version.
Now I have to update software and all its dependencies without a real benefit.
It’s equivalent of buying a new PC because MS tries to force Windows 11.
Lets waste lots of time and resources for nothing.
Just the amount of perf improvements they have added since .NET 4.8, year after year, is staggering.
Having written .NET 5+ apps, and now being back to maintaining a 4.8 app...
There's a lot of quality of life features of the later versions of C# that we're missing out on. My code was a LOT more streamlined in my .NET 9 app.
reminder the .net compiler is IP of microsoft and they state this clearly when you invoke it on any platform other than windows. you are merging your company with microsoft and windows if you use it.
MIT license: https://github.com/dotnet/roslyn
> you are merging your company with microsoft and windows if you use it
That's not how that works. Nothing about the .NET license entitles Microsoft to what you make with the tooling.
It is fully open source so... who cares?