I used .NET Core for a backend API relatively recently (3.1) with no background in .NET prior (mostly javascript/typescript, php, and ruby). I found it incredibly productive and to be an enjoyable developer experience. Entity framework is one of the best ORMs I've ever worked with. Solutions and projects took some getting used to but I like it in retrospect. I now use IntelliJ products as a consequence of having used Rider for that project (developing on a mac) and enjoying the experience. C# as a language is now one of my favourites. I find it hard to convince colleagues and peers to give it a chance (mostly ruby and javascript devs) which is a shame.
Extremely similar background here, similar feelings after working with .NET / modern C#. I even, semi- subconsciously perhaps, wanted to dislike it -- because I thought it was MS-ish, and ASP-ish. But really, it's a first class citizen and especially so the last few years as it's become very fast & received a ton of cross-platform support.
Once over the [quite low IMO] initial 'hurdle', it's easily amongst the most productive & best-supported "platforms" I've ever worked within.
Same goes for Elixir and Scala, it's mostly because from an outside-in view it really hasn't changed much (when 'looking' at the language and framework in question). Technical changes are relatively easy, cultural changes.. not so much.
Some time ago I had the misfortune to direct a C#/ASP.net web project, and that project turned out to be the first web project where the backend was singnificantly later than the frontend. Even though the backend had 2 senior developers and the frontend only 1 junior developer doing React.
Since then I am not able to take seriously the saying of .net to be "incredibly productive".
I am returning to Java ( Spring Boot, Spring Cloud and IntellJ ) after a long period with C# and .NET core. What a step backward it is! Really the .NET platform is leaps and bounds better than anything offered by Java today (at least when speaking about Spring).
If you can, you can give a try to Quarkus,
while the doc is not up to the level of Spring, in term of ergonomics, configuration, hot reload, test containers, this is closer to what .NET does, by example annotations are optional and are resolved at compilation not at the execution.
.NET and C# as a platform are evolving extremely fast compared to many other runtimes and languages. In fact, it's kind of been converging with JavaScript and TypeScript. I have a small repo here that highlights this: https://github.com/CharlieDigital/js-ts-csharp
If you stopped working with .NET and C# around version 4, the language itself has transformed.
Local functions, pattern matching, records, and more!
Yes, I think it is the best ORM in terms of productivity, but it is very, very slow. This is usually not a concern for internal enterprise applications that only have a few people using them at a time though. I guess the other issue is just an issue with ORMs in general - you lose a lot of the in-built features of your sql database, which as projects progress, can ultimately result in you writing the same amount of code as if you didn't use the ORM.
You also can't switch programming languages without rewriting the entire database section. Personally, I stopped using ORMs altogether because I find that they make easy things a little easier, and hard things harder, which isn't a very good value proposition overall. They don't really save me time anymore.
I don't think its a common opinion that its very slow. It builds queries and executes them very quickly compared to most.
It does have a built in footgun where for some structures it defaults to invisibly lazy loading sub-collections, you can (almost certainly should) disable that and specifically tell it to populate that data in the first query using Include() or any of the other projection mechanisms. Is it possible you had that?
As others have noted, that's very outdated information.
The other thing is that for all ORMS, for the small amount of queries where it really matters, you should drop down to hand-written SQL anyway if the juice is worth the squeeeeze!
Well, for plain old websites Ruby on Rails I think is on par with ASP.NET MVC.
For Web API maybe Go is a reasonable contender if you put up with the boiler plate and verbosity.
As for mobile apps, I didn't encounter anything as productive as Xamarin while being reasonably multiplatform.
I didn't do desktop apps since ages but I remember QT and Embarcadero's C++ builder as being quite productive.
But one platform to do it all? There isn't other. Javascript is today used everywhere but I wouldn't quite qualify it as productive or performant. And countless frameworks and libraries competing with each other kind of makes it a mess.
JavaScript is productive once you stop listening to all the high level abstracts and complications. Vanilla JavaScript is beautiful and highly productive. Right up there with c# for server side ops.
Interesting! I’ve recently made a switch from C# to TypeScript and I’ve found prisma to be such a relief from working with entity framework.
Not that entity is bad in any way, it’s just not as productive. Which is sort of how I have it with most of the journey into TypeScript. It’s just a really great environment especially in Azure Function apps, and a massive cadeau to Microsoft for making the node in docker such a first class citizen in their Azure environment!
In many ways I feel like TypeScript is a mix of the best of Python and C# and that’s just wonderful, for me.
But writing things like Odata APIs in .Net sure has some benefits from the massive work Microsoft has done with the .net and C# environment since moving core into the main .net or however you describe it.
So now I’m not sure where I am going with this, I’m probably just very appreciative of the work Microsoft has done for us enterprise developers in non-tech enterprise in the past few years.
> Entity framework is one of the best ORMs I've ever worked with.
It is good, but it's just better to learn TSQL/SQL Server if you are on a windows stack. Shouldn't use it as a crutch especially if you working on the back-end side. Entity framework was created to make data access easier for the front-end people.
Maybe full on EF/EFCore is better, but I know with basic Linq to Sql I often needed to check the generated SQL because sometimes it was non-intuitive how to get it to generate the simplest form possible (my biggest example was to do a 3 part join I had to list the tables backwards from the way I expected, doing the other way lead to a weird bunch of subselects, though note this is also in Framework so maybe they simply fixed the SQL compiler in Core).
I'm using ASP.Net Core for a couple personal projects for the first time, and it's pretty decent. I'm using nginx as a proxy, and I'm able to develop and test everything on Windows, and publish directly to a Linux test server. I have a lot to learn, especially for handling some web requests at a lower level, but I've been pretty impressed so far.
Interesting. I’m a rails developer, and to me one of the core strength of rails is active record (altho some might disagree). How would you compare it with rails active record, and which part do you say it’s much better?
Btw, I know this is superfluous and very shallow, but for some reason, I can’t get over the C# syntax because of how enterprisey it is. I much prefer ruby, but I guess it’s a matter of preferences and taste
I have worked with .NET for a long time and recently did some work with Java, node and python. .NET has a lot going for it but i feel MS is making things more complicated than they have to be. When I need to achieve something a little off the beaten path in the non .NET technologies this is often pretty straightforward to achieve whereas in .NET I have to find some obscure interface and overrides to implement and then deal with weird side effects. I think .NET has become too big for its own good to be maintained by one party. The documentation also has a lot of volume but almost no structure. When .NET started out it was pretty coherent but in the last few years it felt very disjointed without a central design philosophy. Don’t even mention desktop development which is a complete mess since Windows 8.
Maybe I am too negative on .NET but personally find the open source alternatives easier to work with and more fun.
I find this very intriguing. As a runtime, .NET exposes a lot of high and low level stuff to the developer.
Can you give me an example of this offbeat thing you wanted to do that involves overriding an obscure interface?
.NET is big, but if you are using it for web app, your focus is only on that set of libraries. Comparing with similar stacks, none of them cover the area .NET covers.
Also, look at python. People don't see it as big because it does not have an IDE that asks you to select projects and what not, making it seem like it is a tool small enough for their work. However, if you combine every library or framework that covers what .NET does in Python (Web, Desktop, Gaming, System, ML) you will find Python is also just as large.
I have the same experience as the parent comment.
For example, I wanted to have a process that runs both the asp.net service, a background discord bot, and another asp.net service.
On any other platform, it's just a good old "console app" equivalent, and you can start multiple services in your main function, catch SIGTERM, and control each service on your own.
On .NET, the project type has to be some weird Microsoft.Web.SDK things if you wanna run asp.net, and the IDE/build system would figure out what dependencies to build. And if I wanna run other services in the same binary, tough luck.
Why can't ASP.NET just be constructed as a regular console app, where you pull in nuget dependencies, instead of a completely different app type, for example.
Blazor IMV is more sane than React. It is an SPA that is structured around routing and pages, which happen to have component hierarchies in them.
React is the other way around. Routing in React seems to be an afterthought. And I hate it with a passion.
Page based way of thinking (or "screens" if you will) is a better way to do web dev.
Also, the Dependency Injection system is extremely productive. State management in Blazor is very easy and a breeze to use.
If not for the intricacies of hosting models, and a slightly large default build size for the full WASM client mode, Blazor would have replaced React / Angular / Vue by now.
>The interop layer than you have to go through to do a lot of stuff is actually quite tame. It just needs more time on Linux.
What do you mean?
I have software on prod on Linux for years and the only problem I had was lack of some fonts installed that made some problem when it comes to pdf generation
Compared to JS SPAs such as React/Vue/Angular, Blazor obviates a huge amount of toolchain complexity, multi-language and transpilation impedance, and jank of leaky abstractions building a component model on top of Javascript.
Having worked with a mix of these, I found Blazor to be clearly much simpler, approaching though not quite reaching the simplest possible implementation for a component based UI.
I think it's probably more a matter of what you are used to than inherent complexity. The things you are familiar with seem 'easy' and the unknown seems 'hard'.
Stick with it, it really pays dividends when you get good at it!
I can definitely see the appeal of a simplified .NET lacking a lot of the baggage it has from 21 years. .NET core was an attempt at stripping a lot of stuff out but over time they've had to add stuff back because it turns out telling developers they have to rewrite all their code (or give up on doing things at all) is a bad idea.
Node benefits from being a newer ecosystem (~2009) that started out with simpler goals, so it accumulated cruft more slowly. Ecosystems like node also deploy breaking changes more often - .NET 1.0 software can still be run on a modern Windows machine using the latest regular framework, though as of 5.0 they finally decided to kill existing .NET code (the old framework still works, 5.0 and later just use a separate one).
I'm personally still writing and maintaining .NET 4.x code and some of it is working stuff I wrote in ~2005 and it has been serving me well that whole time. I have extensive experience with C++, JS, Python etc and C# is still my first choice when it comes time to solve problems (Python is a somewhat distant but still respectable 2nd place - the REPL is great.)
From time to time I've been able to solve difficult problems with built-in .NET tooling - I wrote a custom compiler for a DSL from scratch entirely using built-in 4.x features and it can do hot reloading, generate debug information, allow me to set breakpoints in visual studio, etc. I simply can't get this anywhere else.
I have used it since 2001, though Friday (and continuing next week and for the forseaable future). My biggest problems are:
* OOP is celebrated in the ecosystem. It's time to face the truth: the mainstream (i.e. not smalltalk) implementation of OOP is fundamentally flawed. I have done some pretty fancy stuff with aspnetcore and, OH BOY, does it take a while to unravel and understand that decoupled OOP wet dream.
* Nobody does the high performance stuff in the real world. DDD (which has several valid merits) has many idioms in netcore that are fundamentally incompatible with writing high performance code. You might be able to dilute DDD to achieve tighter code, but if you value explicit clarity above all else then you have limits. Modern procedural languages suffer from fewer opinions when approaching the best of both worlds.
Really this is a rant about OOP and, disagree with me about OOP being broken or not, OOP and OOP idioms are deeply entrenched in netcore (F# included).
- In later versions of .NET, struct enregistrering is very powerful, it promotes struct's contents to CPU registers. You can write high-performance and allocation-free implementations for value objects, monads and wrappers of all kinds without much issues nowadays.
- Guarded devirtualization helps a lot if you heavily rely on interfaces because it allows further inlining and reduces method calls cost.
- Unfortunately LINQ is no match to Rust iterators which get easily vectorized. However, there are low-allocations and simd-ified implementations which might help with your goals. See https://github.com/asc-community/HonkPerf.NET
After all, DDD requires special care when describing its domain definitions in code but you really don't have to go OOP route nowadays for the core logic of your applications. Also records and record structs make it very easy to define contracts and state on the go without having to go with tons of boilerplate I keep seeing in a very much DDD-oriented project my team is responsible for.
Do you have any links to stuff about struct enregistering and guarded devirtualization? I'm familiar with the concepts and have gotten .NET to do the latter intermittently but if there's documentation on how to make them happen reliably that'd be great to see.
It's not like MS wants to make it easy to use a functional or procedural paradigm.
I tried to bind an IConfiguration section to a record but I couldn't since in condensed form a record lacks a default constructor. So I had to write a class like record and add Init to each property to make them immutable.
I think this is a valid critique. But then, most of the development (C aside) has been a victim to OOP.
I have begun to think that OOP creates more problems than it solves. Added complexity and performance loss being the biggest. It's insane if you peek into a big projects where many developers came and went and each of them read an article about what it seemed an interesting design pattern and tried to implement them.
You can have some kind of procedural programming if you use classes just to store data and use static methods. But the frameworks are OOP and there is no way around that unless you write your own frameworks.
I am a big fan of Mike Acton's Data Oriented Architecture speeches, but I didn't find a way to implement something similar in C#.
For those interested in something better than OOP, here's a few links:
.NET now has a lot of functional stuff. It has a whole functional language (F#), that can natively interop with .NET libraries (even if they are written in C#)
C# itself has many functional constructs.
With the modern minimal APIs, you can create a single file web application servers, without ever creating any objects.
OOP is the bread and butter of .NET, just like Java.
-ish. You can't have true FP without a high level of referential-transparency, that's something the CLR doesn't support due to restrictions in the CLR's type-system, which in-turn restricts languages on-top of the CLR like C# and F# (and we see that in the limitations in the F# language).
Back to C# though: Function-references are passed as strongly-typed delegate objects (which include a bound `this` reference), but there's no reification of function parameters: so there's no spread-operator for parameters, nor currying, nor equivalence of delegate-types. There are workarounds for most (but not all) of these issues, but it just results in the tedious writing of wrappers everywhere, which drives me mad.
A trend with C# that I've noticed is that it gets a lot of cool features, but each cool new feature always has a wart on it somewhere.
* User-defined implicit type conversion, but only between user-defined types, not between interfaces, and there's no in-box interface that expresses such a conversion for use as a generic constraint (i.e. we still need an `IConvertTo<T>`).
* If you use interpolated strings you're forced to use CurrentCulture. You need to jump through a lot of hoops to use InvariantCulture or your own interpolation formatting logic (improved in C# 10, but still doesn't address the jump-through-hoops problem).
* Generic type covariance/contravariance, but only for interface types, and when the type-arguments are reference-types.
* Generic type constraints, except they don't participate in overload resolution.
I left OOP when I left Ruby back in 2015. I won't be going back to OOP ever. I use Elixir now.
How much C# is functional these days? I know linq had the beginnings of it waaaay back in 2010 but do you see a shift in more c# devs going functional instead of OOP? Or is it just another JavaEnterpriseFactoryFactory.cs
OO and functional are orthogonal, and C# has both. Definitely more of the former, but it's catching up on the latter - records, immutability, pattern matching etc.
In .Net the F# language is specifically targeted at functional programming. If thats your interest, you're probably better checking that out over what C# supports.
>I left OOP when I left Ruby back in 2015. I won't be going back to OOP ever. I use Elixir now.
Lucky you! But most of us, poor folks, are getting paid to write software in an OOP language. The huge majority of the most used programming laguages, C aside, are OOP.
>How much C# is functional these days? I know linq had the beginnings of it waaaay back in 2010 but do you see a shift in more c# devs going functional instead of OOP? Or is it just another JavaEnterpriseFactoryFactory.cs
You can write pretty functional code with LINQ, pattern matching, records. Discriminated unions will be also added in the future.
In the last two projects I was working on, people mostly uses procedural programming. Where you could find some design patterns it was mostly juniors wanting to show off.
They added record classes (amd record structs) a year or two ago. Discriminated unions are one of the top requested features and they keep hinting that they might make it into the next version but it keeps getting pushed back.
How, in your opinion, does “mainstream” OOP differ from what Smalltalk OOP was/is?
I tell people Alan Kay’s 97 OOPSLA keynote “I invented the term object oriented, and this is not what I had in mind”, but I find it difficult to articulate to people who are doing “mainstream” OOP, what they’re missing. It’s like trying to explain the taste of salt.
Just curious if you have any better way of explaining it.
Oddly, I’ve been learning Elixir/Erlang for the last year, and though it’s definitely not OOP, there’s something oddly resonant about it with my Smalltalk past from 10 years ago.
Agents with explicit messages are much closer to Smalltalk OO than virtual methods implemented via dispatch tables, with statically typed arguments.
OOP has its place. I think it's decent in the small - when you're dealing with data structures which inherently have state and need to maintain invariants - and it's decent, in the agent form, in the large, where you have encapsulated state in separate agents which communicate with one another using messages, as long as you have other actor-model things like fault tolerance.
It's in the middle, when you're trying to write a big app filled with communicating mutable objects with lots of mutual references, that things can get pretty sticky. My experience is that it's better to favour complete knowledge of concrete types than to minimize knowledge of concrete types and leave them open to extension. That is, pattern matching is generally preferred to polymorphism and it's better to get a compilation error when you add a new subtype than it is to try and always squish your new subtype into a polymorphic interface straitjacket to use virtual dispatch instead.
There are other problems with object orientation, particularly the way it produces very pointerful code and isn't friendly to - doesn't take advantage of - high latency high bandwidth memory.
> OH BOY, does it take a while to unravel and understand that decoupled OOP wet dream.
If you are referring to ASP.NET then I think you might be describing DI and IoC more than OOP in general.
The evolution of ASP.NET has definitely be one of embracing DI and IoC design patterns.
With ASP.Net Core the conversion is complete as the foundations of that framework are built on DI and IoC design principles.
However, the trouble with DI for newcomers is it can be very hard to understanding what's going, only because of much of the action happens in code that is not visible.
It also means anyone using the framework really has little choice but to also adopt DI and IoC design principles, otherwise they'll just find themselves fighting the framework.
Yeah I think you're right it may be the DI and IoC .. I've seen a lot of complaints about that. Usually that it's not 'simple enough'.
But .NET is not a beginners coding environment, it is instead designed to support being all things to all people. That includes including high assurance, and high performance. The DI and IoC is there to support high assurance.
.NET is also quite reasonably approachable for beginners, but as a tool with advanced capabilities too there is of course a bit more of learning curve, and if the reasons why the IoC are there are explained earlier on it helps people to understand that it is designed very sensibly, just with a bit more scope than beginner oriented platforms.
In ASP.NET's case I think DI is useful for the way the framework is structured. It just makes it easier to register services using DI container and call the code in controllers and other services.
You can, how ever, to not use DI at all. Write the business logic in controllers. Write business logic in static classes. Write business logic in regular classes but instead of registering in DI container you instantiate them yourself.
The irony is that if you look at a framework like Nest.js, it's pretty much a reaction to how difficult it is to manage and scale pure express/Node projects without more structure and higher order patterns like DI and IoC.
My personal tipping point was the realization that OOP forces you to first figure out how you solution maps to OOP, before figuring out (or iterating on) how it maps to code. It creates nothing more than accidental complexity: https://emangini.com/2021/07/05-accidental-complexity/
I love .NET. It is highly productive, reasonably performant and you can competently write any kind of software using it beside systems programming. It is an excellent jack of all trades, and you can move with ease from game programming, to web applications, to desktop software, to small glue programs and utilities, to mobile apps, to web frontend and what not.
In the future even systems programming might be possible with push towards native apps and direct memory access. If at some point it will be possible to disable the garbage collector and manually manage memory, .NET could be used for everything.
For a company investing in .NET is a good idea since you can move with ease a developer from one role to another. And even if you don't move the developer, having a mobile developer who can read and understand the code for the backend APIs can be quite beneficial.
For me, personally, working with .NET was quite a win. I moved from desktop apps to web, then, when I got bored I moved to the gaming industry as a game developer and now I am again a happy web developer writing microservice based web apps. Meanwhile I also developed a few mobile apps for myself.
> If at some point it will be possible to disable the garbage collector and manually manage memory, .NET could be used for everything.
While I haven't seen anyone disable the GC completely, plenty of people avoid using it in the Unity/gamedev world. You simply avoid allocating memory (outside of loading) and the GC isn't a problem when it has no work to do. Making sure none of your code allocates at runtime is only difficult if you "don't optimize prematurely" (write shit code without any understanding or regard for performance).
Being able to disable GC would be great for WASM clients! Would solve the Blazor WASM perf issue.
.NET was already used for systems level programming, you can read about an operating system build in it called Midori, by MS for research. While slower for some things it was actually faster for other things due to being able to make smarter runtime analysis than VMless code.. there's a fascinating series of articles about it floating around online.
> (Note: there’s some debate on whether it’s 20 or 21 years, but Microsoft’s Professional Developers Conference in October, 2001 definitely already referenced .NET in production systems)
I can clear this one up.
I was lead on a .Net production system launched in August, 2001. It's 21 years.
Not sure why you're being downvoted, as these are real pain points. As other comments have pointed out, .NET rebranding sucks and is confusing (like .NET Core, .NET Standard, etc.). And the questions around the GUI toolkits don't help. WinForms is the only thing that is (still) consistently developed - kind of.
I do not think it is an issue about (re)branding. Each of those things that people refer to as confusing (.NET Framework, .NET Core, .NET Standard and now standalone .NET) are distinct and separate parts. I think it's more that .NET spent the best part of its existence Windows-only and to transition to being cross-platform requires some hefty changes that necessitated clearly defined stages (windows-only .NET Framework, then early-stage-cross-platform .NET Core 1/2/3 and then end-result .NET 5/6+) and a clear way to write library code targetted such that it can be used by certain cross-sections of those stages (.NET Standard).
They've managed the transition well on the technical side of things - as you can see there are plenty of people who are happy with the end result. But it's clear from comments that pop up here that they've really missed the mark when it comes to actually describing the intent behind the whole project, because a surprising number regard it as just an unnecessary exercise in rebranding.
The WinForms repo is actually also quite dead. There are fixes here and there are but no major things in the horizon. Apparently they want to focus their efforts on MAUI and WinUI, both of which are not even close to production ready.
Try to build desktop app in Ruby or in Python, no one cares about desktop apps. If you want to build native desktop apps you go with QT or something C++ based.
.NET branding being confusing is a theoretical problem. When you work day to day with the code you don't care and it does not affect anything I work on. It is not like it somehow affects compilation or some of my code stops working. I use .NET 4.8, .NET standard and .NET Core and now .NET 6 in projects and no problems there.
Have you tried to make a desktop app in Ruby or Python? Java desktop apps are also not having some great approach where stuff was changing through years AWT, Swing, JavaFX.
Of course Electron is winning but it is basically a web app wrapped around.
Winnig from the side of the business or developer, but absolutley not as a user. UX ist just so bad with many Electron apps. They feel slow (and usually they are), they miss a lot of OS specific usability. That's not a win-win.
> The .NET desktop strategy has sucked since Build 2011
only if you need cross platform. WPF is pretty good and WinForms still ain't broken. oh you said strategy .. I think the strategy is wait for something to get popular, maybe something will happen with BlazorWebView
Is there something confusing about just ".NET" as a brand moving forward? It was annoying at first when we went from .NET Framework -> .NET Core -> .NET in a short period of time, but it's just been .NET since then, which seems fine to me.
Myth 9: .NET development is dominated by Microsoft, not a community
Myth 10: if Microsoft decides to kill .NET or go in a new direction, you are screwed (at least more than with the mentioned community-developed open source alternatives).
I guess apples-to-apples benchmarks are so hard to agree on that any statement of the form "A is slower than B" is always to some degree a myth. If that's the author's position, fair enough. But if we actually want to make comparisons, "C# is faster than Rust" is a bold claim.
C# is not faster than Rust - but you can get near Rust performance with all the safety and memory management goodness.
On benchmark C# is giving go run for its money! But again, it is easy to get carried away by benchmarks. Go-routines are a killer feature, .Net async/await come with gotchas.
The weird space of .Net/.net is because the first 15 or so years - it was hostage to Windows. There by tainting its mind-share and engineering culture.
The only snags I see with async/await are when developers don't know what they're doing and try to force async methods to be synchronous with .Result. If you async it all the way down the stack: your web controller methods are async / your program's main is async, you'll have no issues. It's actually great, because you don't even have to know the internals or what it's doing.
The reason why it's a myth worth dispelling now is that The (legacy) .NET Framework, which used to be ".NET" back in the day, actually was hilariously slow for any kind of web or networking work. It had decent CPU crunching power, but also only on Windows machines.
Comparisons of benchmarks with C# vs. Rust or whatever are unproductive and it's a shame that the article focuses on that. The reality is that you can write C# or F# code today, focus on solving your problem instead of performance, and have it handle a production workload admirably well. That used to not be true circa ~2010. Thankfully it is true now :)
I disagree. It was pretty good even back in 2005. There were a couple of very large high traffic sites I ran on it back then.
I wouldn’t use it now because the big cost is always humans in a project and anything .Net turns into a damage amplifier because of the amount of fettling and dealing with churn you have to do to get anything done. Even with .net 6.
This is my experience with dotnet. Considerable amount of legacy code coupled with different web frameworks along the way. While the app was slow, I found the amount of time it took to make changes to be the unbearable part, mostly a whack a mole situation. Maybe I worked with some bad developers, but they all acted as if dotnet was the best thing ever with constant mentions of dependency injection and blaming the GAC for problems they clearly created..
I believe StackOverflow has been running with .NET since they started in 2008, and they were pretty surprised by the scalability and performance. They do use Windows servers though. They've been reasonably open about sharing their architecture.
The .NET Framework HttpClient was considered really slow by the .NET team themselves. In .NET Core they scrapped the old code entirely so they could build a good one.
Because people equate startup time with speed? Seriously, Java was never slow compared to the things that I actually saw people comparing it to. I've seen people pick Javascript over Java, because of performance and it just made no sense. Notably that incident was over 10 years ago, when JS was actually pretty slow relative to today.
I can't think of a time when Python, PHP, Perl, or Ruby were faster than Java and yet I saw people acting as if they were.
I don't know whether modern Java is slow or fast compared to other languages since it tends to be fast enough for many applications these days. Yet Java earned a reputation for being slow in the early days, may that be due to the startup time of the JVM when Java applets were embedded into web pages or the lacklustre performance of overly ambitious applications built upon a (then) immature platform. Even though those issues were dealt with in one form or another (e.g. applets dying off as well as the development and improvement of the JIT compiler), the reputation has been hard to shake. I suspect that much of that is due to a "fool me once, shame on me; fool me twice, shame on you" type of attitude. In other words, people haven't bothered to see if it has improved since early Java did not live up to the early hype.
Probably because C doesn't have a garbage collector or interpreter. And despite all the evidence suggesting that bytecode interpreters on top of JIT compilers with generational GC is plenty fast enough for a huge number of applications, with additional benefits like memory safety and lower development time, devs are still convinced that big == bad and slow.
Maybe. Probably not as bad and slow as you think it is. .NET and Java really don't have the performance overhead that everyone thinks they do, but a corollary of that is C and C++ aren't as fast as you think they are. All that GC tuning you see on JVMs is the same work you do converting to data oriented code in your favorite systems language, you're just fighting the memory wall. While GC's can do it smarter than a human can, they just can't do it for free.
> If it really wasn't slow, why would they have to defend it? We don't see "C is not slow" articles.
Because there’s a justifiable concern from some about a bytecode system being slower than raw machine code. After all, bytecode requires, at a minimum, interpretation to run. And with JIT systems, there’s still a cost associated with it.
You don’t see “C is not slow” because no one is arguing that it is.[a] There’s nothing faster than machine code[b].
[a]: Maybe back in the day when assembly was still king? If the internet was as prevalent 20 years ago as it is now, I’m sure you’d’ve seen articles arguing “C is not slow” compared to assembly.
[b]: Ignoring optimizations. Machine code is as close to the processor you can get.
Once over the [quite low IMO] initial 'hurdle', it's easily amongst the most productive & best-supported "platforms" I've ever worked within.
That's the best summary of the .NET stack, unfortunately it requires first-hand experience to figure it out.
Since then I am not able to take seriously the saying of .net to be "incredibly productive".
If you stopped working with .NET and C# around version 4, the language itself has transformed.
Local functions, pattern matching, records, and more!
Yes, I think it is the best ORM in terms of productivity, but it is very, very slow. This is usually not a concern for internal enterprise applications that only have a few people using them at a time though. I guess the other issue is just an issue with ORMs in general - you lose a lot of the in-built features of your sql database, which as projects progress, can ultimately result in you writing the same amount of code as if you didn't use the ORM.
You also can't switch programming languages without rewriting the entire database section. Personally, I stopped using ORMs altogether because I find that they make easy things a little easier, and hard things harder, which isn't a very good value proposition overall. They don't really save me time anymore.
The benchmarks model simple, but real world scenarios. It has breakdowns by EF, Dapper (the StackOverflow "micro-ORM"), MySQL, PG, and raw ADO.NET.
It should be noted that EF and EF Core are not the same thing; EF Core is more or less a full rewrite: https://docs.microsoft.com/en-us/ef/efcore-and-ef6/
Recent benchmarks have EF Core catching up to Dapper. You can read more about Microsoft's focus on performance for EF Core here: https://devblogs.microsoft.com/dotnet/announcing-entity-fram...
It does have a built in footgun where for some structures it defaults to invisibly lazy loading sub-collections, you can (almost certainly should) disable that and specifically tell it to populate that data in the first query using Include() or any of the other projection mechanisms. Is it possible you had that?
The other thing is that for all ORMS, for the small amount of queries where it really matters, you should drop down to hand-written SQL anyway if the juice is worth the squeeeeze!
For Web API maybe Go is a reasonable contender if you put up with the boiler plate and verbosity.
As for mobile apps, I didn't encounter anything as productive as Xamarin while being reasonably multiplatform.
I didn't do desktop apps since ages but I remember QT and Embarcadero's C++ builder as being quite productive.
But one platform to do it all? There isn't other. Javascript is today used everywhere but I wouldn't quite qualify it as productive or performant. And countless frameworks and libraries competing with each other kind of makes it a mess.
Not that entity is bad in any way, it’s just not as productive. Which is sort of how I have it with most of the journey into TypeScript. It’s just a really great environment especially in Azure Function apps, and a massive cadeau to Microsoft for making the node in docker such a first class citizen in their Azure environment!
In many ways I feel like TypeScript is a mix of the best of Python and C# and that’s just wonderful, for me.
But writing things like Odata APIs in .Net sure has some benefits from the massive work Microsoft has done with the .net and C# environment since moving core into the main .net or however you describe it.
So now I’m not sure where I am going with this, I’m probably just very appreciative of the work Microsoft has done for us enterprise developers in non-tech enterprise in the past few years.
It's also lacking support for a lot of data types on PG.
It's crazy that EF Core has providers for everything from SQL Server to CosmosDB to Google Spanner to in memory DBs.
LINQ and expression trees are probably one of the best features of .NET.
It is good, but it's just better to learn TSQL/SQL Server if you are on a windows stack. Shouldn't use it as a crutch especially if you working on the back-end side. Entity framework was created to make data access easier for the front-end people.
Edit: thanks :)
Push they’re buttons all the time calling them Microsoft fanboys… that will get them going. Secretly they like it.
Btw, I know this is superfluous and very shallow, but for some reason, I can’t get over the C# syntax because of how enterprisey it is. I much prefer ruby, but I guess it’s a matter of preferences and taste
Think of that as 37 times as much AWS bill for your projects in RoR.. what were you saying about the syntax ¯\_(ツ)_/¯
Maybe I am too negative on .NET but personally find the open source alternatives easier to work with and more fun.
Can you give me an example of this offbeat thing you wanted to do that involves overriding an obscure interface?
.NET is big, but if you are using it for web app, your focus is only on that set of libraries. Comparing with similar stacks, none of them cover the area .NET covers.
Also, look at python. People don't see it as big because it does not have an IDE that asks you to select projects and what not, making it seem like it is a tool small enough for their work. However, if you combine every library or framework that covers what .NET does in Python (Web, Desktop, Gaming, System, ML) you will find Python is also just as large.
On any other platform, it's just a good old "console app" equivalent, and you can start multiple services in your main function, catch SIGTERM, and control each service on your own.
On .NET, the project type has to be some weird Microsoft.Web.SDK things if you wanna run asp.net, and the IDE/build system would figure out what dependencies to build. And if I wanna run other services in the same binary, tough luck.
Why can't ASP.NET just be constructed as a regular console app, where you pull in nuget dependencies, instead of a completely different app type, for example.
Dead Comment
The interop layer than you have to go through to do a lot of stuff is actually quite tame. It just needs more time on Linux.
React is the other way around. Routing in React seems to be an afterthought. And I hate it with a passion.
Page based way of thinking (or "screens" if you will) is a better way to do web dev.
Also, the Dependency Injection system is extremely productive. State management in Blazor is very easy and a breeze to use.
If not for the intricacies of hosting models, and a slightly large default build size for the full WASM client mode, Blazor would have replaced React / Angular / Vue by now.
What do you mean?
I have software on prod on Linux for years and the only problem I had was lack of some fonts installed that made some problem when it comes to pdf generation
I dunno, Blazor feels like the one ASP framework that makes sense. MVC, Web Apps, Web Forms all feel impenetrable to me.
Having worked with a mix of these, I found Blazor to be clearly much simpler, approaching though not quite reaching the simplest possible implementation for a component based UI.
I think it's probably more a matter of what you are used to than inherent complexity. The things you are familiar with seem 'easy' and the unknown seems 'hard'.
Stick with it, it really pays dividends when you get good at it!
Node benefits from being a newer ecosystem (~2009) that started out with simpler goals, so it accumulated cruft more slowly. Ecosystems like node also deploy breaking changes more often - .NET 1.0 software can still be run on a modern Windows machine using the latest regular framework, though as of 5.0 they finally decided to kill existing .NET code (the old framework still works, 5.0 and later just use a separate one).
I'm personally still writing and maintaining .NET 4.x code and some of it is working stuff I wrote in ~2005 and it has been serving me well that whole time. I have extensive experience with C++, JS, Python etc and C# is still my first choice when it comes time to solve problems (Python is a somewhat distant but still respectable 2nd place - the REPL is great.)
From time to time I've been able to solve difficult problems with built-in .NET tooling - I wrote a custom compiler for a DSL from scratch entirely using built-in 4.x features and it can do hot reloading, generate debug information, allow me to set breakpoints in visual studio, etc. I simply can't get this anywhere else.
Deleted Comment
* OOP is celebrated in the ecosystem. It's time to face the truth: the mainstream (i.e. not smalltalk) implementation of OOP is fundamentally flawed. I have done some pretty fancy stuff with aspnetcore and, OH BOY, does it take a while to unravel and understand that decoupled OOP wet dream.
* Nobody does the high performance stuff in the real world. DDD (which has several valid merits) has many idioms in netcore that are fundamentally incompatible with writing high performance code. You might be able to dilute DDD to achieve tighter code, but if you value explicit clarity above all else then you have limits. Modern procedural languages suffer from fewer opinions when approaching the best of both worlds.
Really this is a rant about OOP and, disagree with me about OOP being broken or not, OOP and OOP idioms are deeply entrenched in netcore (F# included).
- In later versions of .NET, struct enregistrering is very powerful, it promotes struct's contents to CPU registers. You can write high-performance and allocation-free implementations for value objects, monads and wrappers of all kinds without much issues nowadays.
- Guarded devirtualization helps a lot if you heavily rely on interfaces because it allows further inlining and reduces method calls cost.
- Unfortunately LINQ is no match to Rust iterators which get easily vectorized. However, there are low-allocations and simd-ified implementations which might help with your goals. See https://github.com/asc-community/HonkPerf.NET
After all, DDD requires special care when describing its domain definitions in code but you really don't have to go OOP route nowadays for the core logic of your applications. Also records and record structs make it very easy to define contracts and state on the go without having to go with tons of boilerplate I keep seeing in a very much DDD-oriented project my team is responsible for.
And that's the unavoidable reality. My team are extremely open-minded, but I have no idea how to bring up this subject with them.
I tried to bind an IConfiguration section to a record but I couldn't since in condensed form a record lacks a default constructor. So I had to write a class like record and add Init to each property to make them immutable.
I have begun to think that OOP creates more problems than it solves. Added complexity and performance loss being the biggest. It's insane if you peek into a big projects where many developers came and went and each of them read an article about what it seemed an interesting design pattern and tried to implement them.
You can have some kind of procedural programming if you use classes just to store data and use static methods. But the frameworks are OOP and there is no way around that unless you write your own frameworks.
I am a big fan of Mike Acton's Data Oriented Architecture speeches, but I didn't find a way to implement something similar in C#.
For those interested in something better than OOP, here's a few links:
https://youtu.be/rX0ItVEVjHc
https://youtu.be/QM1iUe6IofM
https://youtu.be/pgoetgxecw8
C# itself has many functional constructs.
With the modern minimal APIs, you can create a single file web application servers, without ever creating any objects.
OOP is the bread and butter of .NET, just like Java.
-ish. You can't have true FP without a high level of referential-transparency, that's something the CLR doesn't support due to restrictions in the CLR's type-system, which in-turn restricts languages on-top of the CLR like C# and F# (and we see that in the limitations in the F# language).
Back to C# though: Function-references are passed as strongly-typed delegate objects (which include a bound `this` reference), but there's no reification of function parameters: so there's no spread-operator for parameters, nor currying, nor equivalence of delegate-types. There are workarounds for most (but not all) of these issues, but it just results in the tedious writing of wrappers everywhere, which drives me mad.
A trend with C# that I've noticed is that it gets a lot of cool features, but each cool new feature always has a wart on it somewhere.
* User-defined implicit type conversion, but only between user-defined types, not between interfaces, and there's no in-box interface that expresses such a conversion for use as a generic constraint (i.e. we still need an `IConvertTo<T>`).
* If you use interpolated strings you're forced to use CurrentCulture. You need to jump through a lot of hoops to use InvariantCulture or your own interpolation formatting logic (improved in C# 10, but still doesn't address the jump-through-hoops problem).
* Generic type covariance/contravariance, but only for interface types, and when the type-arguments are reference-types.
* Generic type constraints, except they don't participate in overload resolution.
And so on...
How much C# is functional these days? I know linq had the beginnings of it waaaay back in 2010 but do you see a shift in more c# devs going functional instead of OOP? Or is it just another JavaEnterpriseFactoryFactory.cs
One of the best functional features in C# is probably pattern matching: https://timdeschryver.dev/blog/pattern-matching-examples-in-...
https://docs.microsoft.com/en-us/dotnet/fsharp/what-is-fshar...
Lucky you! But most of us, poor folks, are getting paid to write software in an OOP language. The huge majority of the most used programming laguages, C aside, are OOP.
>How much C# is functional these days? I know linq had the beginnings of it waaaay back in 2010 but do you see a shift in more c# devs going functional instead of OOP? Or is it just another JavaEnterpriseFactoryFactory.cs
You can write pretty functional code with LINQ, pattern matching, records. Discriminated unions will be also added in the future.
In the last two projects I was working on, people mostly uses procedural programming. Where you could find some design patterns it was mostly juniors wanting to show off.
I think the main problem with functional .net it that all function types are nominal. Functional C# can get really verbose because of that.
I tell people Alan Kay’s 97 OOPSLA keynote “I invented the term object oriented, and this is not what I had in mind”, but I find it difficult to articulate to people who are doing “mainstream” OOP, what they’re missing. It’s like trying to explain the taste of salt.
Just curious if you have any better way of explaining it.
Oddly, I’ve been learning Elixir/Erlang for the last year, and though it’s definitely not OOP, there’s something oddly resonant about it with my Smalltalk past from 10 years ago.
OOP has its place. I think it's decent in the small - when you're dealing with data structures which inherently have state and need to maintain invariants - and it's decent, in the agent form, in the large, where you have encapsulated state in separate agents which communicate with one another using messages, as long as you have other actor-model things like fault tolerance.
It's in the middle, when you're trying to write a big app filled with communicating mutable objects with lots of mutual references, that things can get pretty sticky. My experience is that it's better to favour complete knowledge of concrete types than to minimize knowledge of concrete types and leave them open to extension. That is, pattern matching is generally preferred to polymorphism and it's better to get a compilation error when you add a new subtype than it is to try and always squish your new subtype into a polymorphic interface straitjacket to use virtual dispatch instead.
There are other problems with object orientation, particularly the way it produces very pointerful code and isn't friendly to - doesn't take advantage of - high latency high bandwidth memory.
Is it this one?
https://www.youtube.com/watch?v=oKg1hTOQXoY
Edit: I suspect it is this one, at 10:33 Alan says "Actually I made up the term <<object-oriented>>, and I can tell you I did not have C++ in mind."
If you are referring to ASP.NET then I think you might be describing DI and IoC more than OOP in general.
The evolution of ASP.NET has definitely be one of embracing DI and IoC design patterns.
With ASP.Net Core the conversion is complete as the foundations of that framework are built on DI and IoC design principles.
However, the trouble with DI for newcomers is it can be very hard to understanding what's going, only because of much of the action happens in code that is not visible.
It also means anyone using the framework really has little choice but to also adopt DI and IoC design principles, otherwise they'll just find themselves fighting the framework.
But .NET is not a beginners coding environment, it is instead designed to support being all things to all people. That includes including high assurance, and high performance. The DI and IoC is there to support high assurance.
.NET is also quite reasonably approachable for beginners, but as a tool with advanced capabilities too there is of course a bit more of learning curve, and if the reasons why the IoC are there are explained earlier on it helps people to understand that it is designed very sensibly, just with a bit more scope than beginner oriented platforms.
You can, how ever, to not use DI at all. Write the business logic in controllers. Write business logic in static classes. Write business logic in regular classes but instead of registering in DI container you instantiate them yourself.
We run an high performance, allocation free automated trading platform on .NET. I guess we are nobody…?
Any nice readings you could link me about this view? Thank you!
My personal tipping point was the realization that OOP forces you to first figure out how you solution maps to OOP, before figuring out (or iterating on) how it maps to code. It creates nothing more than accidental complexity: https://emangini.com/2021/07/05-accidental-complexity/
https://youtu.be/rX0ItVEVjHc
https://youtu.be/GKYCA3UsmrU
https://youtu.be/pgoetgxecw8
In the future even systems programming might be possible with push towards native apps and direct memory access. If at some point it will be possible to disable the garbage collector and manually manage memory, .NET could be used for everything.
For a company investing in .NET is a good idea since you can move with ease a developer from one role to another. And even if you don't move the developer, having a mobile developer who can read and understand the code for the backend APIs can be quite beneficial.
For me, personally, working with .NET was quite a win. I moved from desktop apps to web, then, when I got bored I moved to the gaming industry as a game developer and now I am again a happy web developer writing microservice based web apps. Meanwhile I also developed a few mobile apps for myself.
While I haven't seen anyone disable the GC completely, plenty of people avoid using it in the Unity/gamedev world. You simply avoid allocating memory (outside of loading) and the GC isn't a problem when it has no work to do. Making sure none of your code allocates at runtime is only difficult if you "don't optimize prematurely" (write shit code without any understanding or regard for performance).
.NET was already used for systems level programming, you can read about an operating system build in it called Midori, by MS for research. While slower for some things it was actually faster for other things due to being able to make smarter runtime analysis than VMless code.. there's a fascinating series of articles about it floating around online.
I can clear this one up.
I was lead on a .Net production system launched in August, 2001. It's 21 years.
You can build for:
The only thing I'm missing atm is BSD, although it might work with Mono, it is not officially targeted. More: https://docs.microsoft.com/en-us/dotnet/core/rid-catalogSome libraries / frameworks I came across that are definetely worth checking out:
- https://github.com/gnaeus/OperationResult - Rust style error handling for .net
- https://github.com/Tyrrrz/CliFx - Command Line Parser library
- https://github.com/Tyrrrz/CliWrap - Shell exec for c#
- https://github.com/Zeugma440/atldotnet - Audio tagging
- https://avaloniaui.net/ - Cross Plattform UI (WPF Style)
- https://github.com/quozd/awesome-dotnet - Other awesome stuff
- VS Code and JetBrains Rider - alternative IDE for c# development
You can also target Android, iOS, game consoles and microcontrollers.
And they forgot 2...
Myth 7: The .NET branding dept sucks.
Myth 8: The .NET desktop strategy has sucked since Build 2011.
Oh wait, both of those are still true.
They've managed the transition well on the technical side of things - as you can see there are plenty of people who are happy with the end result. But it's clear from comments that pop up here that they've really missed the mark when it comes to actually describing the intent behind the whole project, because a surprising number regard it as just an unnecessary exercise in rebranding.
Try to build desktop app in Ruby or in Python, no one cares about desktop apps. If you want to build native desktop apps you go with QT or something C++ based.
.NET branding being confusing is a theoretical problem. When you work day to day with the code you don't care and it does not affect anything I work on. It is not like it somehow affects compilation or some of my code stops working. I use .NET 4.8, .NET standard and .NET Core and now .NET 6 in projects and no problems there.
We have no more CORE, just .NET.
>And the questions around the GUI toolkits don't help. WinForms is the only thing that is (still) consistently developed - kind of.
MAUI is going to be released soon.
Have you tried to make a desktop app in Ruby or Python? Java desktop apps are also not having some great approach where stuff was changing through years AWT, Swing, JavaFX.
Of course Electron is winning but it is basically a web app wrapped around.
That is such a moot argument.
Winnig from the side of the business or developer, but absolutley not as a user. UX ist just so bad with many Electron apps. They feel slow (and usually they are), they miss a lot of OS specific usability. That's not a win-win.
only if you need cross platform. WPF is pretty good and WinForms still ain't broken. oh you said strategy .. I think the strategy is wait for something to get popular, maybe something will happen with BlazorWebView
But hHow many new official-way-to-do apps have there been? I've lost count.
Actually, what's the current one(s)?
Nobody in this thread has mentioned WinUI yet (https://microsoft.github.io/microsoft-ui-xaml/) which makes me think very few people actually know what they're talking about here.
Myth 10: if Microsoft decides to kill .NET or go in a new direction, you are screwed (at least more than with the mentioned community-developed open source alternatives).
I'd be happy to see these myths dispelled.
I guess apples-to-apples benchmarks are so hard to agree on that any statement of the form "A is slower than B" is always to some degree a myth. If that's the author's position, fair enough. But if we actually want to make comparisons, "C# is faster than Rust" is a bold claim.
On benchmark C# is giving go run for its money! But again, it is easy to get carried away by benchmarks. Go-routines are a killer feature, .Net async/await come with gotchas.
The weird space of .Net/.net is because the first 15 or so years - it was hostage to Windows. There by tainting its mind-share and engineering culture.
Links (a bit old ones about C# low level chops) https://mattwarren.org/2019/03/01/Is-CSharp-a-low-level-lang...https://www.youtube.com/watch?v=mLX1sYVf-Xg
What are the gotchas?
The only snags I see with async/await are when developers don't know what they're doing and try to force async methods to be synchronous with .Result. If you async it all the way down the stack: your web controller methods are async / your program's main is async, you'll have no issues. It's actually great, because you don't even have to know the internals or what it's doing.
Comparisons of benchmarks with C# vs. Rust or whatever are unproductive and it's a shame that the article focuses on that. The reality is that you can write C# or F# code today, focus on solving your problem instead of performance, and have it handle a production workload admirably well. That used to not be true circa ~2010. Thankfully it is true now :)
I wouldn’t use it now because the big cost is always humans in a project and anything .Net turns into a damage amplifier because of the amount of fettling and dealing with churn you have to do to get anything done. Even with .net 6.
If it really wasn't slow, why would they have to defend it? We don't see "C is not slow" articles.
I can't think of a time when Python, PHP, Perl, or Ruby were faster than Java and yet I saw people acting as if they were.
Maybe. Probably not as bad and slow as you think it is. .NET and Java really don't have the performance overhead that everyone thinks they do, but a corollary of that is C and C++ aren't as fast as you think they are. All that GC tuning you see on JVMs is the same work you do converting to data oriented code in your favorite systems language, you're just fighting the memory wall. While GC's can do it smarter than a human can, they just can't do it for free.
Because there’s a justifiable concern from some about a bytecode system being slower than raw machine code. After all, bytecode requires, at a minimum, interpretation to run. And with JIT systems, there’s still a cost associated with it.
You don’t see “C is not slow” because no one is arguing that it is.[a] There’s nothing faster than machine code[b].
[a]: Maybe back in the day when assembly was still king? If the internet was as prevalent 20 years ago as it is now, I’m sure you’d’ve seen articles arguing “C is not slow” compared to assembly.
[b]: Ignoring optimizations. Machine code is as close to the processor you can get.
I didn't spent time to investigate further because I feel that this headline is not really useful in the first place.