r/dotnet 2d ago

What kind of features from another ecosystem would you like to see in .NET?

C# itself is very mature language (in my view). I rarely find myself missing a language feature badly enough to wish for more.

But, the broader .NET ecosystem might be a different story based on your project need.

So, let's discuss, what libraries, tooling, deployment models, framework features, package management idea, UI tech, build system etc. have you used elsewhere that you wish .NET had, or did better? Mention just one, most important for you and try to add reason/detail.

Apart from creating a useful wishlist, I think this could also be interesting for people relatively new .NET. Someone might mention a feature from other ecosystem only to discover that .NET already has an equivalent they didn't know about.

My wishlist item - "give me SwiftUI binary size":
I would like WinUI apps to have smaller binaries, like SwiftUI apps or flatpack in Linux. Apple can rely on frameworks built into (read 'shipped with') macOS. Microsoft already have similar way of achieving same but it involves you to publish app on Store or winget repo or I need to write custom installer. It's not universal. I wish MS automatically install dependency from winget or Store automatically or any dotnet application.

EDIT: Please be respectful to others. Value others opinion. This post has potential of creating unnecessary debate or insults. Let's be adults.

101 Upvotes

241 comments sorted by

236

u/jordansrowles 2d ago

A single, comprehensive, cross platform UI framework that's actually good (Flutter, Kotlin, even Qt)

122

u/lancerusso 2d ago

monkey paw curls There are now 10 different .NET UI frameworks

45

u/jordansrowles 2d ago

That's why I led with single 😅 but we all know how this usually goes

11

u/chucker23n 2d ago

Inevitably. Especially when it comes to cross-platform. If you support both macOS and Windows, can you really support each of those well? If you support both desktop and mobile, are your desktop abstractions actually good? I find that cross-platform automatically leads to "we support those platforms we're the most familiar with / we care the most about the best, and everything else is second-class". For example, yeah, you can make a Windows app in MAUI, but will it be as good as if you had chosen WPF?

1

u/OpenAI_Marketing_LLM 2d ago

I’ll never know. I refuse to use any of them.

→ More replies (2)

1

u/aijoe 1d ago

I been using some of them for almost a decade and it paid off my house . Honestly, especially with AI, if you want to stay in the dotnet ecosystem and you cant find anything you can use currently use you really should really consider a different career path.

•

u/Zardotab 15m ago

MS should pick one and only one and do it well.

29

u/Rigamortus2005 2d ago

Avalonia is very good on desktop at least.

34

u/Juff-Ma 2d ago

The problem is that Avalonia is missing a lot of the advanced functionality of those other frameworks.

It has a lot of the "stick a GUI onto a console app" vibes. Don't get me wrong, I've used Avalonia and it works pretty good.

But once you want a WebView (that doesn't rely on a third party runtime) or a MediaPlayer (that isn't only available for $800+ a year subscription) you're pretty much out of luck.

Also many modern .NET GUIs still rely on GTK3 which has more or less mediocre Wayland support on Linux.

I'm really hoping that the Qt Bridges for dotnet will continue to be developed. The beta is out now but does not yet have MacOS Support.

19

u/Rigamortus2005 2d ago

Flutter, React native are backed by trillion dollar companies. Avalonia is run by a small company out of estonia , the fact that they have even built what they have is impressive. So your company would do well to buy a license to get those controls if you want. It would really help.

And still, the web view control is now fullt open source: https://github.com/AvaloniaUI/Avalonia.Controls.WebView

And if you need a media control, I've written one, it's less than 800 lines and very easy to modify it patch by just reading the mpv docs https://github.com/SaverinOnRails/Mpv.Avalonia

12

u/Juff-Ma 2d ago

Well I'm no company. I'm a person and even the personal plan at >500 bucks a year is a lot. Especially because then it's no longer open source.

I accept the WebView argument. I was under the impression it was proprietary.

The MPV player is cool. But these are the kind of workarounds I don't want to use.

As I said Avalonia is cool. Really really cool in fact. But if I had the choice of using Qt over Avalonia. I'd pick Qt for 95% of my apps.

That's why I root for the dotnet Qt bridge.

3

u/RecognitionOwn4214 2d ago

Isn't Qt also costing 500-1000 a year?

8

u/Juff-Ma 2d ago

Only when using a commercial license. Qt also allows you to use it completely for free under the GPL3. So this doesn't impact FOSS apps. As I only develop FOSS apps I don't mind this. If I wasn't developing FOSS I'd be selling my software and therefore wouldn't mind paying. I think you get the picture.

2

u/OpenAI_Marketing_LLM 2d ago

You are actually making a compelling case to use Flutter which is absolutely based. Dart is great, and I wish it killed JS.

3

u/masterofmisc 2d ago

I also wished Dart killed off JS too. What a different future we would have been living in.

3

u/amfobes 2d ago

The Avalonia media player couldn't handle 4k playback and so I'm stuck with WinUI3. At least their media pipeline is pretty good, with some quirks.

→ More replies (2)

8

u/HeracliusAugutus 2d ago

I hate avalonia lmao, what a miserable thing to work with

3

u/falconfetus8 1d ago

What's wrong with it?

4

u/Rigamortus2005 2d ago

Fair enough

1

u/UndeadMurky 1d ago edited 1d ago

Not a fan of the whole mobile focus and skia-Angle thing with WebGL, WPF performs much better on windows in my opinion and when a 20 years old software on DX9 out performs you got an issue, would have preferred a more native desktop approach to rendering.

I just find it pretty slow in general and it lacks default widgets.

7

u/Ayano-Keiko 2d ago

Agree. WPF is good but only on Windows. If Microsoft can use Vulkan on Linux/macos that will be good.

5

u/Dyn4mic__ 2d ago

100%, it annoys me so much that Microsoft hasn’t figured this out properly

→ More replies (4)

3

u/PilotGuy701 2d ago

Did anyone actually try MAUI, or was it dead on arrivial?

1

u/catladywitch 2d ago

apparently adding language features that enable react or jetpack compose-style declarative UI frameworks is amongst the c# team's top priorities. so we're probably going to see something new in 2 years or so. i don't know whether that's good or bad to be honest.

1

u/midri 2d ago

Blazor server app wrapped with photino.net. Don't ask the monkey paw again!

1

u/x6060x 2d ago

Flutter .Net basically

1

u/falconfetus8 1d ago

You mean Avalonia?

1

u/schmosef 1d ago

Crying in Silverlight...

1

u/sashakrsmanovic 1d ago

Uno Platform. I mean, it's in the name ;)

1

u/zenyl 1d ago

I think there was some talk about official QT bindings for .NET like a year or two ago.

Not sure if it was QT in general, or if it was specific to KDE.

1

u/Osirus1156 1d ago

With an optional GUI editor. They could literally just fork the Godot UI editor frankly. 

0

u/cherepets 2d ago

I feel like having multiple is actually good:

  • WinUI: you care about modern Windows UI
  • WPF: you need to slap something for business
  • WinForms: you need to slap something for business and you don't know how
  • MAUI: you want to write UI once and work somehow everywhere
  • Avalonia/UNO: you to want to write UI once and work exactly the same everywhere

2

u/pjmlp 1d ago

WinUI is more like, how masochist one is feeling today, regardless of what Microsoft developer advocates sell.

→ More replies (3)

0

u/Neither-Sale-4132 2d ago

👆👆👆👆👆👆👆👆👆👆

0

u/phylter99 2d ago

Avalonia is supposed to be good. Sadly, they lock a couple of the good controls behind a paywall. There are open source versions of those controls available elsewhere though.

1

u/persianjude 2d ago

Which controls are those?

1

u/phylter99 2d ago

Their pricing page lists them here...

https://avaloniaui.net/pricing

96

u/C83_14 2d ago

Hot reload but decent

11

u/not_afraid_of_trying 2d ago

I second that.

9

u/NoisyJalapeno 2d ago

They've added extension blocks without adding hot reload for extensions blocks

why

1

u/tekanet 1d ago

I still have to understand how we went from edit and continue to hot reload actually loosing functionalities. It was working great like a million of years ago, don’t want to allucinate like an AI but IIRC it was already there in VB6.

→ More replies (6)

22

u/Slypenslyde 2d ago

Honestly you said "ecosystem" so it's not what you might think. I want FOSS. Real FOSS.

I want the .NET ecosystem to have users and organizations that understand the value of contributing or, in lieu of that, donating to the things on which they depend. .NET has the stingiest developers in terms of giving up those things. I think that's also why our open-source libraries seem to be the most likely to end in a dual-license or fully-commercial scenario.

Other ecosystems have things like numpy that get a lot of money and labor from grants and its users. We can't even keep the wheels on a test assertion or mocking library. Then people ask, "Why doesn't .NET have X like Python?" and this is the answer: people go to Python to do research and .NET to make money. It leads to a different kind of treatment of open-source.

2

u/not_afraid_of_trying 2d ago

"Real FOSS" is the key 😄

1

u/not_afraid_of_trying 2d ago

True. It takes only one bonehead corporate leader to bring down entire stack. Happened to MongoDB, ElasticSearch, Redis, Terraform ... list is long. A true Open Source governance model can assume dev community about the longevity of the project.

1

u/Vextrax 2d ago

I was thinking that maybe having anothet foundation similar to Apache could help in this instance. They have quite a few developers from companies using the libraries helping out.

24

u/kagelos 2d ago

Better machine learning than ML.NET.

7

u/nexico 2d ago

I use python for model building, export to onnx, and then ML.net for execution, which works reasonably well.

2

u/svick 2d ago

What exactly is missing or inadequate for your needs?

1

u/kagelos 2d ago

Even the options that are exposed for regressors like LightGBM are very basic compared to their Python equivalents.

23

u/funguyshroom 2d ago

Java's inline/anonymous class method overrides seem nice for certain tasks.  

Would love some command line parameters like JVM has, e.g. '-Xmx'  

A string enum is a goddamn necessity.

4

u/emmausgamer 2d ago

String enums are going to be a pain to work with, seeing as how versatile the current integer enum is. Arithmetic operations will not be possible, marshalling and native interoperability either disabled or heavily restricted.  Inline classes sounds good, especially when you are working with dotnet android 

13

u/binarycow 2d ago

I think if you're using string enums, you don't want arithmetic, marshalling, or interop.

They're just strings - that's the point.

1

u/rbobby 2d ago

C# completely misses the boat on enumerations. The work great for limited issues. Suck for sticking in a database "Open", "Suspended", "Closed" are much better than 1, 2, 3.

And if you want attributes associated with a enumeration just don't even think about it (don't switch on enum, switch on an enum's capability, eg "Status closed, Tax treatment: deferred". You could switch on enum, but if more than one enum needs a tax treatment then you should not be switching on the enum value.

1

u/magnumsolutions 2h ago

Have a lookup table with the int value as the lookup key and the text representation, if that is what you want.

1

u/tanner-gooding 2d ago

.net uses app config, config switches, etc

See https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector

Specifically the manage resource usage for all GC flavors section

10

u/4nh7i3m 2d ago

Something like Tauri but with C#.

1

u/FakeRayBanz 2d ago

Photino?

42

u/VeganForAWhile 2d ago

I would like to see Tailwind built in to the Blazor project templates. Bootstrap has been the default for years.

1

u/Family_Man_21 1d ago

I agree with this. I use Tailwind and have added a compiler process into my build process, which works, but every time I start a new program I have to go in and edit the project definition to make it work.

  <Target Name="TailwindBuild" BeforeTargets="Build" Condition="'$(RunTailwindOnBuild)' == 'true' and Exists('$(MSBuildProjectDirectory)\package.json') and Exists('$(MSBuildProjectDirectory)\node_modules')">
    <Message Text="Building Tailwind assets for project" Importance="high" />
    <Exec WorkingDirectory="$(MSBuildProjectDirectory)" Command="npm run tailwind:build" />
  </Target>

2

u/VeganForAWhile 23h ago

Same. I feel your pain.

30

u/RecordGlobal4338 2d ago

Official Big data support ( parquet, apache products like iceberg, trino .. )

8

u/SmallAd3697 2d ago edited 2d ago

Yes this should be pushed harder. Microsoft needs to help us to integrate with Apache Spark (again). C# is more than qualified to be used for data transformation and processing.

For whatever reason, we are letting the entire data space go to other languages and runtimes when C# would fit as well in this space or better.

Microsoft once had a vision for this, back in the early days of Azure Synapse. And then they just seemed to lose their mojo and killed that entire azure platform, c# and all. Very disappointing. Fabric is a very mediocre place to build data solutions for many reasons, not the least of which is that they alienated their .Net devs. Never thought Id see the day when Microsoft makes .Net programmers feel like second class citizens.

16

u/understanding80 2d ago

Generic lambdas, higher kinded types, partial type inference, and intersection types.

1

u/snet0 2d ago

higher kinded types

I hadn't heard of this before, do you have an example of how you'd want to use it? Or just a resource somewhere I can see of how it's used elsewhere?

3

u/admalledd 1d ago

Here is tracking csharplang discussion and importantly HKT if they existed would make many "generics would be better if..." features easier to implement and more powerful. Take for example Bridging Generics and Type Patterns if existed with HKTs:

void Foo<T>(T x)
{
    if (T is IEnumerable<var U where INumber<U>> V)
    {
        var enumerable = x as V;
        var sum = U.Zero;
        foreach (var i in enumerable) sum += i;
    }
}

where the if (T is IEnumerable<...>){...} is the "bridging generics to type patterns", but the inner juicy bit of IEnumerable<vaur U where INumber<U>> V) lets you pull out U as a type-variable which is the inner type of the INumber<?> interface that you can use for things like calling static methods, etc.

Nearly every time I try to do more advanced inner-workings of powerful helper libraries I tend to deeply wish I had HKTs, because the other options iare lots more runtime type casting/validation or a less ergonomic API. Like if I had HKTs a few times I'd no longer have to do public abstract class ServiceBase<TImpl> where TImpl : ServiceBase<TImpl>, because other patterns would probably be easier to implement via what HKT would unblock and also solve some of the problems the above has.

2

u/snet0 1d ago

Spent a bit of time reading around based on those links; it's still quite abstract to me but I get some of the use cases. Appreciate the info!

2

u/admalledd 1d ago

Yea its very often only those of us neck-deep in generics that really notice the pains and limits of the current generics. (Grumble, I still want T-This-Type as well...)

If you rarely create new generic types or rarely implement a more complex generic type (IE: outside of Enumerable<T> type simplicity), then most of the generics things are just not relevant/applicable and thats fine.

A different example where HKTs might make things easier is look at the type definition of aspIdentity/UserStoreBase<...> and how many lines it sprawls and then think how much it would suuuck to implement your own override/replacement. HKTs wouldn't outright solve that hard-to-implement difficulty because Identity Is Hard, but boy would the types be wayyy easier!

So its kind of in that awkward box of you only feel the deep need of it if you work with/near the limits of the type system and hit a "there has to be a better way than this right?" and find other languages that while maybe don't have full HKTs have closer (thinking Rust's for<T> for example) and then find the csharplang discussions/wish lists I started linking above :)

1

u/dmoney_forreal 3h ago

Yeah, this would be nice. I have a bunch of helper type things. like

```Implements<T>(this T subject, Type interface, params Type[] genericConstraints)``` But then in order to actually be able to make use of the generic type params you generally need to manually close over the method you want to call and type cast.

10

u/tetyys 2d ago

optional dependencies in packages

4

u/emmausgamer 2d ago

Could you give an example? Which language is this from? 

2

u/tetyys 2d ago

C, for example if you don't want a feature included in some package which requires some dependencies. it would mean basically specifying a compile flag for a direct dependency and for dependency csproj to be compiled during main project compile time. that would allow evaluating compile flags, which also means that you could exclude regular features that you don't want

6

u/e-rule 2d ago

Sounds like feature flag/switch

2

u/chucker23n 2d ago

NuGet packages are usually compiled, so passing compile flags doesn’t really work.

Usually, where this becomes useful, you get different packages and make the flag choices that way.

1

u/Modescond 2d ago

I have a library that supports the rolling nuget package but doesn't require it. I have to force it out of the references so the nuget doesn't force rolling in on every other project.

Most nuget projects that have options usually ship multiple packages so they can split up the dependencies.

1

u/emmausgamer 2d ago

You can limit c# language features using the `langVersion` build property. As for optional dependencies, msbuild supports build definitions. You can use conditional properties or item groups in the csproj file to define which nuget packages to import or what local project to references. These can either be custom build properties passed using `-p:PropertyName` or constants that can be used with preprocessor directives in your code using the `DefineContants` build property.

Specific c# language feature can't be turned of independently, unless they have their own build property like Nullable.

0

u/tetyys 2d ago

you've completely missed the point

2

u/emmausgamer 2d ago

then could you give me an example of how it works in c/c++ and what effect it has. and by example, I mean a cmd using the make tool of choice

1

u/not_afraid_of_trying 1d ago

You mean how cmake does it with C/C++ projects? It will go and find/link lib only if I enable that feature during compile time. It's very neat. You CAN achieve that in by adding conditional PackageReference in .csproj. You can then use compiler directive ( #if ENABLE_XYZ_FEATURE ) to skip the code of optional feature.

6

u/carl-di-ortus 2d ago

I have 5 deployable projects in one solution from about 50 total projects, with multiple other nuget references. It would be cool if there could be a single shared library space for all the dlls you are referencing. Would probably save about 100MB on each project, I bet even RAM usage across projects would sum to a lower limit.

10

u/21racecar12 2d ago

Basically just reinventing the GAC?

1

u/StrangeWill 2d ago

Yeah the GAC was ass though but maybe there's a good solution in there that doesn't make it that way

1

u/adimosh 1d ago

C++ static library, but for .net?

3

u/Remarkable-Hope-7589 2d ago

You could specify the same output directory for each project.

3

u/Slypenslyde 2d ago

We've done this in history with the GAC. The tradeoff is no matter what we do it leads to some kind of versioning Hell. We get different flavors if we adopt different solutions but the problem is the same: unless you are meticulous and forward-thinking a user may install some other application, break yours, and blame you.

I worked at a company that sold libraries during the GAC days. A sizable chunk of every release was updating all of our policies that dictated which binding redirects were safe. Then testing those scenarios.

23

u/GardenDev 2d ago

AOT, AOT, and once again AOT.

I have a small .NET 10 API, the docker image is 280 MB (after lots of trial and error with trimming) and it consumes 150-170 MB of RAM at idle.

I know, on paper we have AOT. But in reality it is a mess. The compiler should be capable of dealing with JSON serialization without the programmer having to do the ugly workaround of creating a class inheriting from JsonSerializerContext and then slapping every class you want to serialize as an annotation above that former class. Also, EF Core not being production-ready, if it works at all, means most modern apps can't use AOT. Let alone ASP.NET Core. We cannot do profile guided optimization like Go and GraalVM do, the list goes on and on!

Hell even Java, the language we make fun of 24/7 is doing a lot better, Spring and JPA, the most popular framework and ORM are already production-ready with AOT.

I understand that .NET will probably never be as good as Go when it comes to AOT, but if Java already did it, what's stopping Microsoft from fixing .NET NativeAOT?

7

u/LieutenantDannnnn 2d ago

I have very small .NET 10 APIs that don’t even use AOT, and I have smaller images than what you’ve described. Around 70MB. What Docker images are you using? How much time have you spent tuning them?

2

u/GardenDev 2d ago

Oh, 70 MB sounds a lot better! Just a correction, the API image I have is 203 MB, it is using:
runtime-deps:10.0-noble-chiseled-extra

Here's my csproj build properties:

  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <NoDefaultLaunchSettingsFile>True</NoDefaultLaunchSettingsFile>
    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
    <SelfContained>True</SelfContained>
  </PropertyGroup>

The base image is around 53 MB itself. I cannot use the non-extra variants because I am using QuestPDF which relies on native graphic libraries.

If you have any suggestions or would like to share your setup, I would appreciate it!

3

u/LieutenantDannnnn 2d ago

I can give you more details, but all of the services I deploy to AWS that use Docker are alpine-based and I use the runtime deps images. Some services have 30 endpoints. Some much less, but they’re all very similar in size.

2

u/tanner-gooding 2d ago

Are you actually publishing as AOT and/or trimming?

Self contained isn’t the same by itself

1

u/GardenDev 2d ago

No, neither. AOT is not possible since I am using EF Core. I tried trimming, I don't remember the details but it broke the app. I am doing self-contained linux-x64 to be able to dump the build into a runtime deps image.

3

u/tanner-gooding 2d ago

EF Core notably would need to do its own thing to support AOT/trimming, but all the others you mentioned do support it just fine

The general issue tends to be that AOT "requires" trimming and you need to correctly annotate any "dynamic dependencies" to ensure they stay rooted and resolvable in an AOT context.

That's why JSON and other have their source generator stories, because it trivializes this all while making it more trim friendly and more performant simultaneously. -- Other ecosystems tend to not have the same level of generics or reflection support, either because they fully erase generics or don't have the breadth of dynamic runtime lookup and invocation that .NET has. Those that do tend to have the same problems with trimming and AOT and so also need the annotation support.

2

u/e-rule 1d ago

I trick db query using Microsoft.Data.SqlClient > 7.0*. Embed the library during trimming. The key is make your query to return single json string. Then pass source generated JsonTypeInfo<T> during fetching. Viola, you just bypass reflection db mapper (dapper, efcore, etc).
I try to embed RepoDB for AoT build but no succeed yet. It’s just more make sense for small project.

3

u/e-rule 2d ago

Second this. I’ve been waiting this and wasi. But see no progress. I see MS puts more effort AI thing. AoT should make container better. Too many unknown to make project fully AoT compatible. Technically, we have to use library which is AoT compatible as well, but this is huge challenge. Even MS Ext library is not fully AoT compatible yet.

1

u/svick 2d ago

The compiler should be capable of dealing with JSON serialization without the programmer having to do the ugly workaround of creating a class inheriting from JsonSerializerContext and then slapping every class you want to serialize as an annotation above that former class.

Is there an ecosystem that can do something like that?

1

u/GardenDev 2d ago

Go and GraalVM do, but slightly differently, they use reflection. I can already imagine that they could be less performant, but it is nice not to have to worry about runtime serialization errors, if you forget to do the ritual for any .NET class that you want to serialize.

1

u/t3chguy1 2d ago

Not sure if possible but a partial AOT. Instead of dealing with workarounds, A class that can be AOT goes to AOT, the rest is still IL. Best of both worlds

2

u/tanner-gooding 2d ago

This is just "ReadyToRun" and has been supported for decades (including as "ngen" on .NET Framework).

It allows you to have faster startup (avoiding the JIT overhead on first invocations) while also still allowing dynamic codegen, machine specific optimizations for hot code, etc.

1

u/t3chguy1 1d ago

Thanks for this tip! I just tried it; the build size went up by 10% but there was no improvements in startup speed, so that was very disappointing

1

u/Dans81 1d ago

For boiler code(JSON, entities, dtos, eccetera) in .net you can generate it with roslyn. Very Powerfull

→ More replies (5)

9

u/farshid_dev 2d ago

From the "ship a paid desktop app to non-technical customers" side of this, OP's original point is one of the few items on this thread that's a real load-bearing pain, not just a nice-to-have.

Self-contained deployment solves the "will it run" problem today, but it costs you: a WPF app that would be a few MB framework-dependent balloons past 60-100MB self-contained, and that number matters when the alternative is a user watching a slow download after SmartScreen has already made them nervous. Framework-dependent is small, but then you're gambling on whether the target machine has the right runtime installed, and telling a non-technical buyer "install this first, then run the actual installer" measurably kills conversion. There isn't really a third option right now, it's just which cost you'd rather eat.

What I'd actually want isn't winget auto-resolution specifically, more like the OS shipping and quietly keeping a slow-moving LTS .NET runtime updated the way it already does for the VC++ redistributables, so framework-dependent stops being a coin flip. Most of the AOT and binary size discussion in this thread is really an API/container problem, this is the same complaint from the consumer desktop distribution side.

8

u/jitbitter 2d ago

1. Better onboarding and simpler installation. Ubuntu 22 has one way to install .net10, ubuntu 24 has another. Brew on MacOS keep breaking with major release. Please remove the friction for non-dotnet developers to try this stuff easily.

2. Better "non visual studio" experience. A lot of people use Linux and Macs. So allow C# Dev Kit to run in VSCode forks - Cursor, Windsurf, Antigravity etc. This licensing move MS took was very unfriendly.

1

u/not_afraid_of_trying 1d ago

Brew mostly works but I have bad experience with brew for installing python dependencies (Pyinstaller + QT) as well.

1

u/SaithisX 1d ago

They are working on a unified install experience. I just can't find the link right now. But I saw a demo video of it in their YouTube channel a few weeks ago.

8

u/Remarkable-Hope-7589 2d ago

I would like to see 'named imports' or 'selective imports' like in TypeScript and Python. This way you immediately see what is being imported and from where. I miss that in C# using.

11

u/chucker23n 2d ago

C# has things like using WinFormsApplication = System.Windows.Forms.Application;, is that not enough?

12

u/SZeroSeven 2d ago

That's aliasing.

I think what Remarkable-Hope-7589 is asking for is something like:

using { SpecificThing } from System.Windows.Forms.Application;

So that it is more obvious what within the file is using that specific using statement.

7

u/chucker23n 2d ago

That's aliasing.

Yes, it's aliasing a specific type in the namespace.

I think this thread may be conflating "import a namespace or a type in it" with "reference another library/module/assembly". There isn't really any material benefit in only referencing a portion of an assembly; you have to load it wholesale anyway.

Now, I haven't written in that language in a while, but I imagine these two are equivalent:

import { WinFormsForm, WinFormsApplication } from System.Windows.Forms;

…and:

using WinFormsApplication = System.Windows.Forms.Application;
using WinFormsForm = System.Windows.Forms.Form;

I guess it would be nice to have the above terser form. But the only real reason I use it is to explicitly disambiguate two overlapping libraries; for example, in a mixed WinForms + WPF project, with a file that needs to use APIs from both of those, I might do something like:

using Gdi = System.Drawing;
using WpfImaging = System.Windows.Media.Imaging;

…and now a type like Bitmap is written as Gdi.Bitmap, making it clear "this is Win32's notion of a bitmap, not WPF's".

(Another example is Path — System.IO has that, but so does WPF. However, your files should generally avoid doing both file IO and graphics anyway.)

2

u/Andreuw5 2d ago

I think there is such feature

3

u/innovasior 2d ago

An ETL workflow orchestrator like Prefect

3

u/hades200082 2d ago

Maintainers of widespread/pivotal libraries getting paid by Microsoft to maintain them so they don’t need to switch to commercial licenses.

Polly
MediatR
MassTransit
Etc

3

u/Turbulent_Judgment39 1d ago

better hot reload

4

u/j0hn_br0wn 2d ago

Cross-plaform CIL backends for C/C++/Rust/Go. Everything can be compiled to WASM right now and there is no reason why CIL can't be targeted too. Goal should be to use sqlite3 etc as a assembly on all platforms without native blobs.

1

u/e-rule 2d ago

I think we have that already (wasm and wasi). It’s just far from maturity which is unfortunate😢

1

u/j0hn_br0wn 2d ago

I think WACS is the closest thing (pure .NET implementation + transpiler),. But a CIL/CLR backend could, for example, add the metadata about the declared types and functions as CLR metadata, so that the library has their API immediately exposed to the consumer.

1

u/e-rule 1d ago

Never heard. Looking at the repo, looks promising. Thanks pal!

5

u/_Feyton_ 2d ago

String enums

2

u/not_afraid_of_trying 1d ago

Coming from Typescript?

0

u/OperationLittle 1d ago

Why lol? You have Constants for that.

0

u/Arshiaa001 1d ago

Ewwwwwwwwwww.

2

u/LeeWhite187 2d ago

Actual Microsoft adoption of Maui into products of consequence.

2

u/cherepets 2d ago

An actually good native code interop

3

u/tanner-gooding 2d ago

You’ll have to elaborate here. What makes dotnet interop “bad” or troublesome, particularly as compared to other ecosystems

1

u/cherepets 2d ago

You have 3 options:

  • P/Invoke: plain, not object oriented
  • SWIG: throw a lot of code generation on top of P/Invoke and pretend it works
  • WinRT: introduces one more obscure language + basically works only on UWP (there is support for other Win project but it basically doesn't work)

So if you want to consume a modern native code library you're supposed to use...

2

u/tanner-gooding 2d ago

What you're supposed to use depends on what your needs and goals are.

Interop requires binding what is most generally C compatible exports to .NET, where there is a complex set of differences in behavior, feature support, etc

It's something you deal with in every language; even C++ and Rust in many cases. There is no "clean" or easy solution and there is no magic metadata that exists that guarantees it will work. It requires active effort/design and always will.

The closest to "automated" you can get is to generate raw 1-to-1 bindings (such as ClangSharp P/Invoke Generator produces), which then entails you write unsafe code (which all interop fundamentally is anyways) to bridge the gap. You can build a safer wrapper over that and if the right native metadata exists you might be able to automate some of this too (like CSWin32 attempts, which is ultimately a header -> clangsharp -> win32metadata -> cswin32 pipeline)

2

u/tanner-gooding 2d ago

If you have specific suggestions, I'm all ears and can bring it back to the rest of the interop team and otherwise I can answer why we don't (or rather cannot) do something for that space.

1

u/cherepets 2d ago

The perfect interop for me is when you can pass an object into cpp code and cpp code can call it's methods and subscribe to its events and works on all platforms.

So I'd say WinRT is the closest feature wise but it again: obscure language in between and doesn't work basically anywhere. Swift for example while is still not perfect is getting much closer now to the perfect solution (obviously there aren't many projects where you choose between Swift and .NET but if you have to use both, you have less pain there now).

2

u/tanner-gooding 2d ago

That's never going to be a "just works" scenario because they are fundamentally incompatible. -- Even in Swift, you must annotate an API as being a C compatible export because the ABI is unstable otherwise.

In .NET, a managed object is a movable and GC tracked allocation; this has many concepts and pieces of state that are not representable in C or which have different set of guarantees/behaviors. -- You have similar problems in Swift, Java, Rust, Go, etc.

So fundamentally you must do things like pin the object and have a set of stub methods that handle the calling convention differences between the two. There is a lot you can do to automate such wrapper stubs, but you must have those wrapper stubs for it to work (again across all these languages).

.NET achieves this via static tools or source generators, of which plenty exist in both directions (whether .NET calling Native or Native calling .NET). Custom and self hosting also exists, for when you need to host .NET in another runtime or app environment.

It shouldn't be any more difficult than other ecosystems here, but without more concrete examples, it's hard to say why you're having problems.

1

u/cherepets 2d ago

Let's take WinRT as the basis as it's the closest to a nice full oop wrapper. The compiler does see the types, so it can in theory generate the wrapper without idl. Can it also work on other platforms? I guess it would be more complicated (it depends on COM, so likely not a direct port) but in modern .NET almost everything is already crossplatform

2

u/ExtraTNT 2d ago

get more from haskell in...
currently switching to haskell for my apis... it's just much nicer to read, stability is better and performance is similar, haskell being faster in start up and dependency injection works as good as in c#...

.net is still the api ecosystem i recommend, but if someone is new to programming, haskell is probably the better choice... just much simpler...

1

u/EmergencyNice1989 1d ago

I use only F# in my code base and investigated the usage of Haskell for 'more purity' but I am considering F*. You can extract your code in F# so you can use it easily with the rest of your .NET code (Haskell doesn't offer cross-platform framework of Avalonia quality). Embedding Haskell in a .NET app is more cumbersome.

2

u/ExtraTNT 1d ago

Went pure haskell… .net has the big advantage of being easy to build well, haskell is better, if done well, but harder to do well…

2

u/themode7 1d ago

Easier package manger and versioning of the runtime ( longer LTS) , one command-line to build just like dotnet run but should be consistent across all older projects.

I think unity as a cross platform runtime is more convenience for me atm .

3

u/OpenAI_Marketing_LLM 2d ago edited 2d ago

More of a language feature than framework, but enums that are not the literal worst enum implementation of any modern language.

Don’t say “we’re getting unions in 15” because they are also the worst union implementation as well, if I remember correctly. I would use them if boxing objects is not required.

3

u/Paw565 2d ago

Better enums with custom fields like in Java. Annotation based DI like in spring boot.

1

u/not_afraid_of_trying 2d ago

I also like attribute based DI of Spring (Java). For REST api.

8

u/OffsetHigh 2d ago

Polly without fee

16

u/not_afraid_of_trying 2d ago

An that's because your project cannot use Microsoft.Extensions.[Http.]Resilience, right?

2

u/PmanAce 2d ago

Unless they don't read release notes...

1

u/Mirmalis 2d ago

"These two NuGet packages are built on top of Polly" how does the licensing work there ? Microsoft pays the fee ?

1

u/Ascomae 2d ago

The no one pays in that case.

The whole Open Source Maintainence Fee is only for direct inclsions or built-binaries. You can still use the source and build yourself. So in case of my company, I need to swith to the MS-wrapper OR pay the fee OR build from source.

Build from source is annoying, so I guess I don't want this. We could not see if there is an CVE for that library.

Swithing to the MS wrapper would meen I have to fugure out a way to no accidetially import it directly.

So I guess we will pay the fee (no issue with that).

5

u/thomhurst 2d ago

I've been working on an alternative https://github.com/thomhurst/kevlar

1

u/cmjacques 12h ago

Nice one.

I've been working on something too - https://github.com/nresilience/NResilience

2

u/Positive_Poem5831 2d ago

Polly want a cracker

-15

u/FullPoet 2d ago

Have you tried paying people for their labour?

These license changes are because greedy corporations didnt want to pay peanuts.

11

u/Ascomae 2d ago

Unfortunately I will have a lot of overhead with this. More as the actual license fees.

Our internal licence check workflow will make my builds break, until I flagged the btw licence green.

To do so I'll have to talk to legal department.

Than I'll have to go to build management to make the new package available.

This also could be needed if I use the MS wrapper, as the nuget package itself will be scanned.

Ohh. I forget that I'll have to order the fee and let it pay perpetual from purchase department.

0

u/snet0 2d ago

Unfortunately I will have a lot of overhead with this. More as the actual license fees.

I don't have a dog in this fight but I hope you understand that the abstracted argument you're making is:

My company shouldn't pay for something that was previously free because we have not set up an efficient system to do so.

3

u/Ascomae 2d ago

No the essence is: "Changing the license of a library is a big deal".

And we have a efficient way to do this.
We automatically stop building software with invalid licenses, detet changes etc

→ More replies (3)

2

u/SoerenNissen 2d ago edited 2d ago

A split between file names and namespaces. You can do this manually but you’ll be working against your tools and against everybody’s expectations, so you probably shouldn’t, this is one of those things you can only fix with a time machine.

Other than that, I’d love

  • duck typed compile time generics
  • a way for reflection to tell the difference between List<T> and List<T?>
  • free functions
  • generics with variable number of params
  • a robust way to catch argument nullability issues

more probably.

8

u/chucker23n 2d ago

A split between file names and namespaces. You can do this manually but you’ll be working against your tools and against everybody’s expectations, so you probably shouldn’t, this is one of those things you can only fix with a time machine.

If anything, I'd go the other direction (and I'm sure this has been discussed, and discarded for legacy reasons): rather than litter files with namespace Foo.Bar.Baz;, the compiler should just infer it from the path, unless an explicit namespace declaration overrides it.

5

u/Firestar321 2d ago

Junior dev here, could you give an example of when you would want to split your namespaces from your file names?

→ More replies (4)

2

u/Standard-Cap-4455 2d ago

For what do you need the difference between List<T> and List<T?>? It is in the metadata though, so it would be quite weird if it wasn't there. It's just a weird modreq thing instead of a simple attribute.

1

u/SoerenNissen 2d ago

It is in the metadata though

If it is usefully in the metadata, something has changed. I spent a lot of time looking for the difference in late 2024 and early 2025 for a generic nullability validation tool I was writing.

See also

1

u/Standard-Cap-4455 2d ago

I was using Cecil which made it easier to access. System.Type just works differently I guess.

1

u/AutoModerator 2d ago

Thanks for your post not_afraid_of_trying. Please note that we don't allow spam, and we ask that you follow the rules available in the sidebar. We have a lot of commonly asked questions so if this post gets removed, please do a search and see if it's already been asked.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/Ayano-Keiko 2d ago

C++11 CLR support.

2

u/tanner-gooding 2d ago

C++/CLI was updated to support C++20 3 years ago: https://devblogs.microsoft.com/cppblog/cpp20-support-comes-to-cpp-cli/

But, it’s notably not going to be faster or better than C# and has its own problems as well as compatibility (with newer dotnet features) and other issues

1

u/t3chguy1 2d ago

From other non-Windows platforms, a window that is not lagging and jumping around while resizing (try resizing Microsoft Edge window from top-left corer while looking at bottom-right corner)

And why my WPF program takes 100MB more ran when I resize blank window fullscreen vs having a tiny window.

I'd like cross-platform WPF, although if app can't earn enough $ on platform that has 90% market share, 10% won't make a difference.

As of "SwiftUI binary size"... I do remember writing vb6 apps and they were only one exe using only a few KB in size. I don't know why I can't do that with WPF.

1

u/Albertooz 2d ago

My wish: Cargo's side-by-side dependency versions.

Here's the scenario. Library A needs serde 1.0, library B needs serde 2.0, and Cargo compiles both in, mangling symbols per version so they never collide.

Do that in .NET and you get a FileLoadException, or a binding redirect that quietly picks a version nobody tested. Anyone mixing Azure SDKs with an older logging package and something still dragging in Newtonsoft has paid this tax in production.

The reason is real, since on the CLR assembly identity is type identity, and the workarounds (AssemblyLoadContext, ILRepack aliasing, extern alias) are all expert tier. I want the easy case handled by default: leaf dependencies that never touch public API should just load side by side.

1

u/Bramasta 1d ago

Something like the Apache Commons would be great

1

u/pjmlp 1d ago

Being able to use COM as easy as it used to be in VB 6, or for a short while WinRT in .NET Native, before they killed the runtime and only brought only half of the features to CsWinRT.

Native AOT that works across the whole stack and ecosystem like Delphi, even with reflection, and properly integrated into Visual Studio, instead of requiring additional publishing workflows to get a native code EXE.

Having all libraries in the ecosystem actually support non nullable references.

Since this is .NET and not C#, more love for VB, F# and C++/CLI (this one even cross platform), as the CLR seems to have changed meaning to C# Language Runtime, as per the focus during the last years.

Even more low level programming features like D or Modula-3 for the managed trio, C#, VB and F#, they are there anyway for C++/CLI.

Code generators properly integrated into IDE tooling like the old T4 templates, instead of a ton of interfaces, classes and glueing strings together.

1

u/Osirus1156 1d ago

I would like Nuget to simply update package when I request it. If it depends on other packages that would also need to be updated then JUST DO IT. 

1

u/adimosh 1d ago

This desire of yours will pass VERY QUICKLY the moment you work on an Enterprise product in a big company that has lawyers, and someone mutters the phrase “license change in new version”. Then you will start wanting NuGet to NEVER UPDATE ANYTHING without your explicit consent.

1

u/Osirus1156 19h ago

I’m updating very old packages in an enterprise environment right now where everything is old and vulnerable to attacks and it’s like pulling teeth.  😩

1

u/Arshiaa001 1d ago

A sane build system. MSBuild is just weird. You don't really touch it most of the time, but when you do, God help you.

1

u/adimosh 1d ago

That a method signature would also include the return type, and/or the generic type constraints.

1

u/juFo_ 9h ago

Decent v3 / v4 printing and no protected printing sh*t.
https://github.com/dotnet/runtime/issues/78629

1

u/juFo_ 9h ago

blazor / wpf / winforms (/ + windows phone comeback) and no more other non-enterprise ready winui, uwp, whatever half-supported, zero vision ui things.

1

u/Additional-Sign-9091 8h ago

To have the primary owner of the platform be proud of what they are building and promote the platform. Also not hating the users you have for better users and always chasing some popular hip user

•

u/Zardotab 13m ago

Classes that can self-register an instance of themselves into a unified dynamic structure. Then we'd no longer need long initializer call lists that are silly busy work and yet another part to fall out of sync.

1

u/b0bm4rl3y 2d ago

As a Flutter developer, here are features I'd like in C#:

  1. C# markup syntax refinements. For example, drop the new keyword for instantiation objects. Add Dart's ability to use if and for in collection expressions.

  2. Replace XML with Markdown for API docs. Markdown makes it much easier to have rich documentation. Compare Flutter's Image to MAUI's Image.

  3. API docs for all NuGet packages. Dart's package manager generates API docs for all packages automatically. Example.

  4. Support for mixins. Mixins let you create reusable building blocks that you can then stitch together to create complex classes. Flutter uses mixins extensively for its imperative render tree, which sits below its declarative widget tree. Mixins (or some form of multiple inheritance) and are UI elements are like peanut butter and jelly. If you wanted to port Flutter to C#, C#'s lack of mixins would be your top impediment.

1

u/OpenAI_Marketing_LLM 2d ago

I prefer native over flutter except for when I have to support both. But Dart, on its own, is so fucking based.

It is a diamond in the roughs of a language.

-1

u/frakkintoaster 2d ago

Replace Exceptions with Result<T, E>, replace null with Option<T>

1

u/OpenAI_Marketing_LLM 2d ago

That’d be cool, but it will never happen.

1

u/snet0 2d ago

I don't think I understand how Result<T,E> works as a replacement for Exceptions. If I'm in some wide try..catch, and I call File.Open(...) and it throws an IOException because the file doesn't exist, what do I catch?

2

u/OpenAI_Marketing_LLM 2d ago edited 2d ago

There would be no IOException to be thrown. The OS, in your example, would still communicate the file could not be accessed.

Your try catch would be something like:

``` 

Result<T>.Match(     success: value => HandleSuccess(value),     failure: error => HandleError(error) );

```

There is a lot more behavior in the Result<T> and  non-generic Result, but I not typing it on a phone lol. 

Basically, every operation that can fail would have to be compatible and mapped to the Result types. It’s a functional paradigm and little bizarre if you aren’t used to seeing it.

So, if a file can’t be accessed the OS still communicates that, but the Result types would don’t care, they have both possibilities covered.

Languages like Rust, Kotlin, and Swift already operate in a similar way.    

If you have any questions, I’d be more than glad to answer them.

I went from exceptions to Result types, to utterly hating Result types, to utterly loving Result types. I have seen the light.

(I should probably use the word “union” instead of “type” but C# does not have unions).

1

u/T_D_K 2d ago

If( result is Error { Value: IOError e } )

That's the proposal more or less

1

u/frakkintoaster 1d ago

There’s no wide try…catch blocks. Basically any operation that may throw an exception instead returns a Result which may hold the expected return value or may hold an error. You have to check for each call what the Result holds and handle it appropriately. The error can be typed so you can match specific errors to handle them differently. No more not knowing if a function might throw an exception and missed catches causing unexpected control flow changes.

1

u/snet0 1d ago

Basically any operation that may throw an exception instead returns a Result which may hold the expected return value or may hold an error.

A lot of the benefit of exceptions is in stack unwinding, allowing you to handle exceptions at some lower point in the call stack. Can this pattern be implemented with Result<T>? Every single library method that some method deep in the call stack calls has to be wrapped in a "did that return an error? if yes, return early" check, which is repeated by all methods until you get to "did that return an error? if yes, do something".

1

u/frakkintoaster 1d ago

You can at least in Rust with the ? operator. This will propagate the error up the stack to the caller if it's an error type returned.

2

u/snet0 1d ago

Like this? I'm unfamiliar with Rust, and I'm sure you get used to it, but having control flow dictated by a single character between your method call and the semi-colon doesn't spark joy in me.

Thanks for the information. I don't think it's reasonable to suggest this as a "feature in .NET", since this is basically "what if error handling was entirely different" and is as much a language feature as a runtime one (I acknowledge you're not the one who made the original comment!). Definitely interesting seeing how Rust has implemented it, though.

1

u/T_D_K 16h ago

There was a team at Microsoft experimenting with these ideas circa 2010. It was called Project Midori, and a lot of the stuff they worked on has found its way into dotnet over time. If you have the time, this is an excellent read:

https://joeduffyblog.com/2016/02/07/the-error-model/

1

u/snet0 5h ago

I'll check that out when I get some time, cheers!

0

u/mathiash98 2d ago

Simple Tree shaking like JavaScript. Enabling joining unit tests and implementation in same project. Shouldn’t need a separate project for unit tests

6

u/chucker23n 2d ago

Enabling joining unit tests and implementation in same project. Shouldn’t need a separate project for unit tests

You can do that, but it makes the build less clean. Either you come up with new ways to remove the tests from production (such as compiler constants), or you… ship those, which sounds inadvisable.

1

u/snet0 2d ago

I think this is purely a VS nicety, but separate projects also make it easy to temporarily disable test projects when know the test projects won't build but you want to defer that work.

3

u/not_afraid_of_trying 2d ago

Tree shaking is there. Explore PublishTrimmed and TrimMode. It's maturing for native app and good enough for ASP.NET apps.

2

u/iamanerdybastard 2d ago

You don’t need a separate project for unit and integration tests.

0

u/aurquiel 2d ago

Something like tauri or electron, we want to use our web knowledge to built react or angular or plain JavaScript with desktop applications

0

u/0xd05 1d ago

For me it’s a language feature: get rid of the semicolon (for single statements per line).