16 ms·
C# 9 top-level programs and target-typed expressions
- belinder 6y agoUnfortunately the new tricks can't be used when the codebase is still stuck on .net framework :(
- lwansbrough 6y agoAllegedly there's an upgrade path from .NET 4.8 to .NET 5.
- keithnz 6y agoif you have built anything on web forms, then you really have no way forward other than rewriting all that. That alone will keep many an enterprise locked on .NET Framework for quite some time.
- belinder 6y agoIn our case not web forms but WCF
- WorldMaker 6y agoYou may want to keep an eye on CoreWCF: https://github.com/CoreWCF/CoreWCF https://github.com/CoreWCF/CoreWCF Though as a heavy WCF user in the past, I'd suggest your best bet is simply to throw out all your binding configs, and build your own REST API or similar backend (gRPC support in .NET 5+ is something often also recommended if you want something more RPC-like and need/want a more binary-serializer like approach, though in 2021 I'd just use JSON and something REST-ish myself). The nice thing about the Interface-driven "contract" approach should be that implementing your own is just a matter of implementing all your contract interfaces and injecting the physical implementations yourself. I realize that can be easier said than done as things accidentally got coupled to very specific styles of bindings over the years and not everyone followed best practices and used the Async contracts so you have to tear out a bunch of synchronous faking code and wire back in Task<T>/ValueTask<T>. But generally, overall, the process was implement the interfaces and remove the "magic" in the process and I often found you end up with something better anyway because it is simpler and prone to less "magic" failures.
- UweSchmidt 6y agoCould you expand a little on that? How exactly does an REST API backed desktop/forms application look like in 2021, and how is the decoupling accomplished?
- WorldMaker 6y agoA lot of the decoupling is naturally accomplished by just not being backward compatible with previous WCF bindings and throwing out the whole mess. The easiest place to start with is your data contracts. You may not have many depending on which side of the RPC/not-RPC boundary you were on, but it may be as simple as creating plain classes that implement those data contracts and then double checking that the Newtonsoft.Json (classic) or System.Text.Json (newer, sleeker) JSON serialization looks nice, deserializes just fine. Generally this work is pretty straightforward and sometimes you can just eliminate the data contract interfaces when you are done (you won't likely need them anywhere else and most of their WCF-specific annotations may just be clutter at that point) and replace them with references to the "POCO" data classes. Some of your service contracts you might also want to explore moving more of the arguments from lists of arguments into simple data classes that serialize nicely to JSON. Then at a high level it's a matter of writing client side class implementations of your service contracts and server-side "proxies" that then call your existing server-side physical implementation of your service contract. At a high level from the client side: - Open a connection to the recipient - Send the JSON serialized data to an endpoint - Wait for the response - Deserialize the response and return it That's basically all that the "bindings" are doing for you in a magic nutshell. You'll just be writing it directly "by hand". In the case of a "REST-like" it would be using something like System.Net.Http.HttpClient on the client side and the HTTP method and your URLs would likely reflect your "operation contracts" (the names of the individual methods on your service contract): `Task<IMyItemDataContract> IMyServiceContract.GetItemDetails(int id)` to `http GET /api/item/details/{id}` for example type things. In general it's a lot of straightforward simple boiler plate to fill out for every interface method ("operation contract"). At a high level for the server side: - Receive a connection - Deserialize the data - Call the appropriate service contract method - Serialize and return the results On the server side, for the simple "REST-like approach" you might want to build a simple ASP.NET (Core) host wrapper. These days you don't necessarily need the full weight of something like ASP.NET MVC and go do all the above steps with just what ASP.NET these days calls "Endpoint Routing". Obviously complications come from figuring out your network topology shifts. Maybe you can't shift your "server" as easily to a real ASP.NET application hosted on a "real" HTTP server somewhere like IIS or Apache or whatever. In some of these cases you can find hints in your existing bindings. (Are you using MSMQ bindings? Use MSMQ or a modern direct replacement like Azure Storage Queues or redis instead of "REST-like" HttpClient and Server, for instance.) There are also ugly "duct tape" solutions such as ASP.NET's "Kestrel" web server can easily be hosted in other .NET processes, if it absolutely must remain an "ordinary" Windows Service or something crazy like that. Once you prove that your "hand-written" clients and service endpoints work, you can generally just throw out most of WCF's binding gunk in your config files and all the attributes on your interfaces. A lot of your code shouldn't change that much in this whole process if it was already just calling the interfaces with again the big caveat being if you need to add Task<T> now, as opposed to having already migrated to it years ago or even using the older uglier Begin/End Async pattern which you often can easily replace with Task<T>). Another option to possibly explore, depending on the nature of your ServiceContracts, how they are expected to feel ("real time?"), is to use SignalR rather than HTTP. (The basics are about the same: make sure everything serializes/deserializes JSON well and change your "operation contracts" to SignalR calls and event responses.) SignalR is also generally hosted on a webserver for negotiating match-making, but actual communications happen in "peer-to-peer" websockets generally after negotiations complete. Azure SignalR has some powerfully scalable hosted solutions, depending on your environment's tolerance for cloud-based tools.
- Analemma_ 6y agoI second the other commenter suggesting you should try to rip off the WCF bandaid and go to a RESTful API as soon as you can. It sounds scary but after the one-time pain of migration we've had way fewer "magic, black box" errors that require insane investigations and hacks.
- starik36 6y agoThere is a tool out there that converts WCF to gRPC. https://visualrecode.com/ https://visualrecode.com/ The guy who wrote it talking about it: https://www.dotnetrocks.com/?show=1728 https://www.dotnetrocks.com/?show=1728
- starik36 6y agoYou can give it a shot with this project. https://github.com/FritzAndFriends/BlazorWebFormsComponents https://github.com/FritzAndFriends/BlazorWebFormsComponents It emulates WebForms component with Blazor. Although I would just start from scratch.
- goto11 6y ago> Although I would just start from scratch. Which is fine if you are a hobbyist developing for fun.
- aliswe 6y agoNot really
- goto11 6y agoThe upgrade path is massive rewrites, something most business are wary of. For good reasons. MS really made a grave mistake by coupling the evolution of the C# language to the .NET version. This means all projects on the .NET framework is now also stuck with an obsolete language version for no good reason. It is becoming a a lot less fun to be a C# developer because you more often will have to work with obsolete tools.
- nycdotnet 6y agoAt work we've been slowly pulling code out of our WebForms monolith. That's still on .NET Framework, and will be forever until we're done killing it, but we can use recent VS and MSBuild with it and we use C# 9 as well. Business code generally works copy and paste in .NET Core, so there's a really good path to migrate to newer stuff, especially with .Net Standard 2.0 being a thing. gRPC is really fast and we have the WebForms monolith call into .NET Core services now so we can improve the back-end without dealing with so much ASPX crap.
- nikanj 6y agoYour programming language either dies young, or it lives long enough to become the very legacy crud it sought to replace.
- wvenable 6y ago> MS really made a grave mistake by coupling the evolution of the C# language to the .NET version. For the most part that isn't true. You can use later C# compilers with older frameworks. Some features do, unavoidably, require framework support. But that being said, the changes in C# aren't often that radical that I feel particularly constrained by older versions.
- Mindless2112 6y agoYou can (and I do), but it is explicitly not supported. If it breaks, you get to keep both halves.
- nullsense 6y ago
- nullsense 6y agoAllegedly there's also a route to the top of Mt Everest. For some of us the "upgrade path" is impassable.
- shireboy 6y agoThere are ways, but definitely can be hard to get unstuck from framework. This came across my newsfeed this am: https://www.telerik.com/blogs/jump-starting-migration-dotnet-core-with-upgrade-assistant https://www.telerik.com/blogs/jump-starting-migration-dotnet... and also, the other day, dotnet rocks podcast had a guy on talking about an upgrade tool. I think it was this one: https://visualrecode.com/ https://visualrecode.com/ He was also discussing the "Strangler Pattern": https://akfpartners.com/growth-blog/strangler-pattern-dos-and-donts https://akfpartners.com/growth-blog/strangler-pattern-dos-an...
- WorldMaker 6y agoNot by default, no. These two specific tricks should work on .NET Framework (some of the other tricks in C# after 7 or 8 require functionality that .NET Framework doesn't have, though). You can ask VS to use the more recent C# compiler with the LangVersion tag in the .csproj: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/configure-language-version https://docs.microsoft.com/en-us/dotnet/csharp/language-refe... Obviously, it's not suggested doing that nor is entirely well supported, but it is at least allowed. Though if you are looking to use top-level programs you probably are working in greenfields anyway that should just be .NET 5+. It's not really a feature that makes a lot of sense for existing codebases as it is more a teaching tool/"quick and dirty command line app/script" tool.
- nycdotnet 6y agoWe use C# 9 in our WebForms monolith and it works fine. Just add `<LangVersion>latest</LangVersion>` to your .csproj file. (This assumes you're using recent Visual Studio version and use a recent version of MSBuild as well)
- linknoid 6y agoThere are a few language features which require a specific type to be defined, but you can define those types yourself. For example, to use record syntax, you need to define this attribute: namespace System.Runtime.CompilerServices { public class IsExternalInit : Attribute { } } And supporting the new indexing syntax requires you to define System.Index and System.Range types, which are a bit more involved, but still pretty trivial: https://docs.microsoft.com/en-us/dotnet/api/system.index?view=net-5.0 https://docs.microsoft.com/en-us/dotnet/api/system.index?vie... https://docs.microsoft.com/en-us/dotnet/api/system.range?view=net-5.0 https://docs.microsoft.com/en-us/dotnet/api/system.range?vie... But pretty much all the other new C# language features I've tried have just worked straight out of the box with .NET 4.7.2.
- bob1029 6y agoThere are many paths out of hell. Check out the windows compatibility pack for all things active directory, WCF & System.Drawing: https://docs.microsoft.com/en-us/dotnet/core/porting/windows-compat-pack https://docs.microsoft.com/en-us/dotnet/core/porting/windows... Winforms is probably a no-go on migration, but you should definitely check out Blazor if you want to develop any new business apps. We have constructed some incredibly complex business dashboards using this framework and cant imagine how some of this would even be possible if we had to move back to a front-end client framework and invent a bunch of JSON APIs. Also, the new Blazor Desktop stuff is extremely exciting: https://medium.com/young-coder/blazor-desktop-the-electron-for-net-ecdcf5c30027 https://medium.com/young-coder/blazor-desktop-the-electron-f... > The first difference is that the WebWindow container doesn’t use WebAssembly at all. Yes, you can run more or less the same Blazor application in WebWindow as you would in a web page. But when you use a web page, it’s executed by a lightweight .NET runtime that’s powered by WebAssembly. When you use it in WebWindow, it will use the cross-platform .NET runtime directly. There is a lot of really amazing stuff coming down the roadmap, so I can easily advocate for enduring some degree of pain to get on this wagon.
- thrower123 6y agoI'm pretty sure WinForms is being migrated. I've built dotnet 5 WinForms apps, anyway. At least on Windows - I wouldn't bet on a Linux Gtk/Qt port any time soon. WPF is probably dead though.
- my123 6y agoWPF is not dead, it got open-sourced and was ported to .NET Core 3.1 onwards.
- ziml77 6y agoMicrosoft wouldn't let WPF die. Anyone writing enterprise desktop applications is using it heavily.
- tonyedgecombe 6y agoAnyone writing enterprise desktop applications is using it heavily. I don't think there is much of that going on anymore. In reality Microsoft did let WPF languish for years, it always felt unfinished. I was very surprised when they migrated it to .Net core.
- emodendroket 6y agoI’m not working with C# anymore but I’m really liking the features they keep adding.
- outside1234 6y agoWho would have believed a decade ago that there would be a RedHat developer blog entry on C# today? If someone had told you that then you would have thought the world would have collapsed in the meantime.
- zwieback 6y agoExactly my first thought. I remember my first steps with C# and it felt very "MS version of Java" and I didn't expect how much a) I would like it and b) how successfully it would spread to other areas
- nightski 6y agoI don't know for sure, but I'd have to guess the Mono project made it on Linux blogs quite often since its inception approx 20 years ago.
- whoisthemachine 6y agoTo me, the benefit of "Target-typed new expressions" is more with bringing consistency to class-scope member declarations and method-scope member declarations, so these two can look the same, and a programmer only has to read one way of declaring new members in C#: public class MyClass { private readonly MyDependency _myDependency = new(); public void MyMethodThatDoesWork() { MyVariable variable = new(); } } As opposed to the (now old, IMO) var syntax/Java-like syntax mixture: public class MyClass { private readonly MyDependency _myDependency = new MyDependency(); public void MyMethodThatDoesWork() { var variable = new MyVariable(); } } Edited for HN formatting.
- keithnz 6y agoI can't see var going anywhere, many times you aren't directly creating a new object, but getting a generated object from something ( like linq) which tends to have more complicated type signatures.
- whoisthemachine 6y agoOh true, there are still use cases where it's valuable. `out var ` also comes to mind.
- nycdotnet 6y agoAgreed that `var` isn't going anywhere, but this feature's best use case is with complex generics/enumerables and things like anonymous tuple types. For example: // old: var x = new List<KeyValuePair<string, int>> { new KeyValuePair<string, int>("a", 1), new KeyValuePair<string, int>("b", 2) }; // new var x = new List<KeyValuePair<string, int>> { new("a", 1), new("b", 2) };
- wk_end 6y agoWow, when I (only a C# dabbler) read about this feature in the article I thought it sounded incredibly silly, but this really sells it. Was there really no better way to create tuples before?
- goto11 6y agoThe article states that the benefit of target-typed new-expressions is that "the type declarations are nicely aligned" compared the use of "var". I think a better justification is that fields and properties does not support type inference, so this can avoid some redundant type expressions for initializes, just like "var" can avoid redundant type expressions for local variables. Of course it would be more elegant if fields/properties supported type inference like "var", but that is a can of worms since you can have recursive dependencies.
- binarynate 6y agoI think that C# is underrated. Although TypeScript is my default language choice for most programming, C# / .NET is my choice for cases where: - high performance is important - or interop with native libraries is required (because C#'s DllImport attribute makes that super simple) Another benefit is that C# is syntactically similar to TypeScript (they were both designed by Anders Hejlsberg after all), so switching between the two languages feels easy. Java and Go are both similar to C# in terms of performance, but interfacing with native code isn't as simple with those languages, and they're also not as similar to TypeScript as C# is (especially Go, which is quite different).
- zwieback 6y agoC# is my goto for Windows, for sure. Is the native interop good in Linux as well? I've never even considered anything like that, would probably gravitate to C++ since that's what I'm familiar with but would seriously consider Go or Java in non-Windows situations.
- josteink 6y agoHow do you think they built the Linux-version of the .NET standard library? ;)
- adolph 6y agoLots of wine?
- scott00 6y agoInterop on Linux works well.
- meibo 6y agoC# on Linux, as of the past 2 or 3 years, has been consistently improving with great tooling, good interop, is open source(MIT) and has the ability to package "native" versions of your app that contain the runtime at negligible space costs for distribution or deployment. Give .NET 5 on Linux a try, you'll be surprised! For me, the work this team has been doing is the example of the positive "change" Microsoft has brought to the open source space. A stellar language with great infrastructure.
- danielovichdk 6y agoI have been programming with c# since 2000 i think. But I do not like where the languages is going. It is becoming way to loose in a sense and it seems that it wants more than it should. If you want to do functional programming, pick a fp language. If you want to do dynamic typed programming pick a dp language. Sure you can mix some things in, but c# is becoming way to scattered imo. And it's not pretty i think.
- thrower123 6y agoI think I'm going to get diabetes from all the syntax sugar... On the more substantive changes, it feels a little like the language designers have been looting F#. Combined with how fast Dotnet Core is moving and how many breaking changes there are there, it does feel like things are getting very fragmented. Stasis isn't good either; just witness the decade or so of stagnation after Java 1.6 as the Sun -> Oracle transition happened. But you can go too far in the other direction.
- emodendroket 6y agoI don’t think they’re just randomly throwing stuff at the wall. These are all things they’ve been talking about for years.
- int_19h 6y agoThe C# language design process is very much in the open, so anybody can go and take a look at the rationale etc. https://github.com/dotnet/csharplang https://github.com/dotnet/csharplang
- lostmsu 6y agoI think it suffers from the design by a self-selected committee now. Very little of recent changes have long-term vision behind them now, and seem to be quick patches. Specifically, I just tried disabling 7.0+ features in an open source project I run, and we only actively used pattern matching for "is MyType inst", ref structs (hi Rust!, that one is really fundamental), and natively sized integers (which are still poorly supported by runtime). Other sugar changes have uses across codebase you can count by fingers of one hand. We also use unmanaged function pointers, but the feature appears ugly in many ways. For our purpose, I'd prefer a tiny bit more flexible DllImport (a hook to give it the dll path at runtime) over function pointers.
- ryandrake 6y agoWow, a full-screen cookie pop-up with a “X” dismiss button in the upper right corner that just causes the full-screen pop-up to re-display. Can it get more obnoxious? This is the second one on the HN front page today [1]. HN tries to avoid paywalled articles, maybe we should also discourage articles that start out by deliberately hiding the content. 1: https://news.ycombinator.com/item?id=26639722 https://news.ycombinator.com/item?id=26639722
- Shadonototro 6y ago+1 for top-level programs -1 for target-typed expressions, it makes code unreadable, i'd rather see var used as field members
- goto11 6y agoYou can't have 'var' for field members since this could lead to recursive type inference. Var does not have this problem since it can only be used for locals.
- kwertyoowiyop 6y agoCan I just create a single .cs file somewhere, and execute it by typing its name? No Visual Studio solution/project shenanigans? That’s my dream. Top-level programs to eliminate boilerplate is a nice related step.
- unnouinceput 6y agowhat do you mean by "execute it"? It's source, you need to compile it and get an executable out of it. This is not Python, an interpreter. But if you want an interpreter for C#, nobody's stopping you to write one. Me, on the other hand, I want Python to become a compiled language. And to those who's going to reply with "PyPy/Cython/Nuitka" I have a question for them: -do show me a .dll from those!
- ninkendo 6y agoTo give an example, in Swift, I can write a hello.swift with: #!/usr/bin/env swift print("Hello") And after a chmod +x, it works. Granted, anyone who I distribute this to will need a swift compiler installed, but that’s to be expected (and similar for Python.) Golang and other “compiled” languages have similar ways of making this work too.
- unnouinceput 6y agoOh, I get it. You mean install some sort of interpreter that is called by the OS for that language. Sorry, I live in real world, where customers don't allow you to install a gazzilion files just to run your application, they expect a proper installer that is under strict supervision by their admin team and you only deliver executables.
- twodave 6y agoI mean, top-level programs are nice, I guess? IMO it's more of a means of attracting non-.NET developers into the fold. I work in a .NET shop and we probably won't use this in our production code. The benefit of target-typed expressions IMO is that it changes property syntax from: public List<Foo> Foos = new List<Foo>(); to simply: public List<Foo> Foos = new(); It may seem subtle, but if you write C# you see this pattern constantly. Honestly, these are the features in C#9 I'm least excited about. I'm much more excited about record types, init-only setters, not to mention the improved pattern-matching and type inference (no more casting nulls inside of ternary operators!). Immutability in C# has classically been pretty cumbersome. I work on a payroll platform where we've managed to work around a lot of that, but we're excited to introduce record types and init-only setters in particular to help with some of the maintenance pain-points surrounding the elimination of side-effects from things like pay calculations.
- gameswithgo 6y agotop level is mostly going to be nice when teaching new programmers. You can just get on with hello world and now have to type all this boiler plate and explain why you have to. But yeah, for "real" programs it is probably irrelevant. But who knows, maybe we will find a use for it. I am mostly excited about the sort-of option type getting rid of nulls option.
- FridgeSeal 6y ago> top level is mostly going to be nice when teaching new programmers. You can just get on with hello world Yeah it seems like kind of a weird thing? “Here’s marginally less boilerplate once, if someone is going to learn to use the language, they may as well learn how it actually works instead of hiding stuff that they’ll soon see anyways...
- johnfn 6y agoYou should see how many new engineers are confused in CS101 when confronted with all of Java's boilerplate just to write a simple "hello world" program. It's a real issue.
- joshsyn 6y agoScala 3 kills C# by a large margin, imho. C# is not a good pursuit unless you are stuck with .Net codebase.
- jongalloway2 6y agoHow so? .NET is 2-4x faster than Scala in benchmarks (https://www.techempower.com/benchmarks/#section=data-r20&hw=ph&test=plaintext https://www.techempower.com/benchmarks/#section=data-r20&hw=...). Do you just prefer the syntax and language features?
- joshsyn 6y agoI like the expressibility, its easy to improve performance in the compiler later.
- HappySweeney 6y agoFamous last words...
- lostmsu 6y agoScala is a great language with terrible (in comparison) tooling. I'd use it (or F#) over C#, if IDE support was not as slow as it is, and if it was comparable to ReSharper/IDEA Java feature-wise for refactoring.
- goto11 6y agoF# is probably a more relevant comparison - it is kind of the Scala of .net. But in any case C# is much more widely used than F#.
- FridgeSeal 6y ago> Top-level programs allow you to write the main method of your application without having to add a class with a static Main method Riveting stuff happening in .Net land! Sarcasm aside, this seems like such a small, oddly-specific, once-off feature that its like...why bother? Any C# devs want to enlighten me here?
- will4274 6y agoWhy not bother? This mindset is one of the core features of .NET-land - Microsoft just goes ahead and implements anything useful. It's why we have a gigantic standard library ("framework") filled with every function under the sun and some multiple times. We didn't have to wait until C++20 to get string.Contains. Sometimes the features Microsoft implements are more useful than others but most of them are a little useful to somebody.
- tonyedgecombe 6y agoIt's not without its downsides though, the language and ecosystem is quite big now. I don't envy people starting out and having to learn it all from scratch.
- twodave 6y agoReally it's much better than it used to be. The people I don't envy are those like my past self who had to contend with .NET 2.0 web forms, the AjaxControlToolkit (and really UpdatePanel in general), bloated heaps of ViewState... the list goes on, and I haven't even gotten past ASP.NET. Most of the improvements that have been made in the last 10 years (aside from maybe async/await, but that pattern is pretty ubiquitous at this point) have served to reduce the amount of idiosyncrasies, not increase them. In general, web programming has increased across-the-board in complexity manifold, regardless of your server-side language. Aside from that I find writing C# to be very succinct and logical these days compared to the past, even taking into account my own learning.
- osigurdson 6y agoThe original post is here: https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9 https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csh....
- syspec 6y agoI really love c# - one of my favrorite languages, but can any one explain the benefit of this new syntax? Person p1 = new(); Person p2 = new("Tom"); Person p3 = new() { FirstName = "Tom" };
- goto11 6y agoYou save typing by not having to repeat the class name.
- twodave 6y agoIn my opinion it's more useful when declaring class members, e.g.: public class SignPost { public List<string> Messages { get; set;} = new(); private List<string> Errors = new(); } In both of the above usages var is not allowed. Often-times instead of a simple list you have something like an IReadOnlyCollection<T> or an equally-abominable custom type that is just a pain to write out 2x for every time you add it as a dependency somewhere.
- aidenn0 6y agoCan anyone comment on cross-platform GUI for .net? Last time I seriously investigated it, Gtk# seemed to be the primary option. Some quick googling found avalonia, but no clue if that's a reasonable GUI to use. I'm guessing MS isn't planning on porting WPF to linux (though I suppose linking with wine might work)...
- mikaelmello 6y agoIt looks like MAUI [1] is the path forward [1] https://devblogs.microsoft.com/dotnet/introducing-net-multi-platform-app-ui/ https://devblogs.microsoft.com/dotnet/introducing-net-multi-...
- aidenn0 6y agoComment streams there indicate that it relies on Xamarin.Forms which is GTK2 and does not support .NET core.
- lloydatkinson 6y agoI'm very cautious of anything from RedHat regarding .NET - some of the worst C# I've ever seen comes from some of the devs working at RedHat in the form of commits to public repositories.