back to article Microsoft emits last preview of .NET 6 and C# 10, but is C# becoming as complex as C++?

Microsoft has released preview 7 of its .NET 6 developer platform and declared new features "done" ahead of an expected arrival for this long-term support version in November. The current version, .NET 5.0, is only supported until May 2022, whereas .NET 6.0 will have a lifetime of three years. Even three years is not very long …

  1. Pascal Monett Silver badge

    "the ability to use operators on generic types."

    Generic types.

    I will likely be downvoted to hell on this, but IMO generic types are the bane of proper programming.

    If you don't know what you're working with, how can you possibly write the proper code to deal with it ?

    Obviously, I am for strong variable typing (in case you didn't guess). I like to know that I'm dealing with a String, or an Integer, or a Long. Variant makes my skin crawl, although there are some cases where I know I won't be able to avoid it.

    Generic types is just handing over all the issues to the compiler and hoping for the best. That is not good when you're responsible for your code.

    There, that was my 2 cents. Blast away.

    1. karlkarl Silver badge

      Re: "the ability to use operators on generic types."

      Whilst I do kind of agree, they do solve a number of challenges and the alternative of classic MACRO's isn't quite as good.

    2. Loyal Commenter Silver badge

      Re: "the ability to use operators on generic types."

      The alternative, in a lot of use cases, to using generics, is to have multiple versions of the same code, for example, once for each type that needs it. Repeated code is definitely a code smell.

      For example, take the List class. Would you rather the language had a List<T>, with one implementation, or one class for every built-in type, such as ListOfInt, ListOfFloat, ListOfString. What about if you want a list of lists? Does the language need to define ListOfListOfInt rather than just allowing you to use List<List<int>>? What about if you want to have a list of your own classes, Foo and Bar, do you want to have to write the boilerplate code yourself for ListOfFoo and ListOfBar? It's a no-brainer that the List<T> class is defined once, has one implementation, and behaves in the the same way whichever T you use it with.

      Generics are a powerful, and pretty obviously needed, tool in the programmer's arsenal. I think you may be making the mistake of thinking that they somehow erode type safety, but if you were going to try to add a string to a list of integers, you'd get a compile error. Whilst the definition of List<T> might be generic, the implementation in the consuming code which might use List<int> very much is not.

      On the other hand, if you were to use a List<dynamic>, to circumvent the compiler's type checking, then you need your head boiled.

      1. FIA Silver badge

        Re: "the ability to use operators on generic types."

        For example, take the List class. Would you rather the language had a List<T>, with one implementation, or one class for every built-in type

        C# has a well defined object heirachy. A list class that takes an 'Object' is fine.

        If you have wrappers for primatives and auto(un)boxing then everythings gravy. :)

        1. Loyal Commenter Silver badge
          FAIL

          Re: "the ability to use operators on generic types."

          Using List<object> erodes type safety in a pretty disastrous way.

          Sure, "ListOfObject" can be sued for a list of ints, but apart from the boxing/unboxing you'd need to do to add and iterate those ints in the list, there's also nothing to stop you chucking a string, or any arbitray object into the middle of that list and then getting a nasty surprise when you try to cast it to an int.

      2. Man inna barrel Bronze badge

        Re: "the ability to use operators on generic types."

        > The alternative, in a lot of use cases, to using generics, is to have multiple versions of the same code, for example, once for each type that needs it. Repeated code is definitely a code smell.

        Having written C++ code for some time, what I miss most when writing C is templates, and generic containers in particular. I ended up writing a cut down version of vector<T>, for the particular type I was using. I gave up trying to implement map<K, T>.

        In some cases, generic code in C can be implemented by representing arbitrary data with void*, which needs casting to the actual type. However, that does not really help implement something like vector<T>. What you actually get is vector<T*>, which is not the same thing at all. One advantage of vector<T> is that the contained data is in one contiguous slab in memory, which makes sequential access very efficient. Also, it simplifies memory management, compared to allocating each item separately.

    3. Steve Channell

      Re: "the ability to use operators on generic types."

      Operator overloads are static function that provide syntax sugar so statements like "hello " + "world" work in an idiomatic way.

      This change is not for functions to operate on (VB style) Variant values, but for cases like matrix functions or complex numbers where type information is available at compile time

    4. Kristian Walsh

      Re: "the ability to use operators on generic types."

      You have misdirected your anger, because C# generics are statically typed.

      Actually, I think you may have confused “generics” with the C# keyword dynamic, which is the “anything goes” equivalent of Qt’s Variant class. Both are a necessary evil when interoperating with runtimes like JavaScript or Python, but they are both huge exceptions to how their host languages normally operate.

      In C#, type rules are applied everywhere, even to generic type parameters (i.e., like C++, but unlike Java): if you create an object of type List<Dictionary<long,string>> then there’s no way to put anything into it except an object of type Dictionary<long, string> or, of course, an object of a type derived from Dictionary<long,string>. And because the typing rules are applied to everything, you can also pass that Dictionary to a function that’s expecting IEnumerable<IEnumerable<long, IEnumerable<char>>, because string implements IEnumerable<char>.

      None of the above is news to you if you use C++, but if your previous experience of generics was in Java, then it would make you sing for joy.

    5. Anonymous Coward
      Anonymous Coward

      Re: "the ability to use operators on generic types."

      This argument sounds more like a criticism of variant or dynamic than of generics....

      Generics are strongly typed, if you define a List<int> then you can do list operations on the list and int operations on the items in it. it's quite handy and lets you do some powerful stuff. ideally you encapsulate generics in something else, so if you want a ListOfShapes, you can inherit from List<Shape> and add the relevant methods for dealing with a list of shapes, and the consumers only see Shapes come out of it.

      The generic math stuff would have helped massively with something i had to implement a couple of years ago, which dealt with AmountOfMoney types, which contain an amount and a currency.

      You can only do certain operations on an amount of money if the currency matches, 1 USD+ 1USD = 2 USD, but 1 USD + 1 GBP is an error...

      or you can add a decorator that can convert the currency, so 1 USD + (new ConvertedCurrency(1 GBP, conversionratetodollars)) = 2.14 USD (where converted currency also implements amountofmoney)

      The problem arises when you have an empty amount of money; null +1 USD = an null ref.

      a NullableAmountOfMoney + 1 USD involves a lot of null and value checking

      a Maybe<AmountOfMoney> involves the same sort of checking

      but a MaybeMoney<AmountOfMoney> that implements the relevant maths operations for money and handled null + 1 USD = 1 USD would have made several hours of explaining to my team why i'd implemented a bunch of weird looking code to make AmountOfMoney + AmountOfMoney work correctly go away.

      (it didn't help that the underlying AmountOfMoney allowed AmountOfMoney * AmountOfMoney but not AmountOfMoney * int, (and also division... money divide money = what? although money / 3 = a new amount of money with the same currecny and the amount / 3, or, a list of 3 amounts of money where the three amounts add up to the original total, all taking into account that currencies have between 0 and 3 decimal places and a third of a cent isn;t valid...)

    6. J27 Silver badge

      Re: "the ability to use operators on generic types."

      Generics are not a Swiss army knife, there are times where they make sense and others where they don't, combined with being able to limit the types accepted there are a lot of good uses of generics... As to handing over the issues to the compiler? I disagree, generics are strongly typed in C# and they don't impact code reliability... They're mostly a way to improve compile-time checking by having the correct type for things instead of having to coerce everything to object and then back to whatever type you need (not type-safe).

      P.S. If we were talking about dynamics, well that's a whole other issue. Dynamics just move your compile-time errors into run time and perform terribly to boot.

    7. bombastic bob Silver badge
      Devil

      Re: "the ability to use operators on generic types."

      IMO generic types are the bane of proper programming.

      C++ recently added 'auto' for this purpose, primarily for use in templates.

      However, outside of a template, explicit typing should be used for a number of reasons, not the least of which is knowing for sure what code will be run given a particular data type.

      If you don't know what you're working with, how can you possibly write the proper code to deal with it ?

      yeah, what YOU said.

  2. karlkarl Silver badge

    CSharp.NET is basically as complex as Java in both language and VM infrastructure (I shudder at the thought of having to port the JVM or CLR to a different platform). This is by design because CSharp.NET is pretty much a failed attempt at EEE on Java.

    C++ is a fairly complex language but since there is no VM layer of complexity to deal with, overall it is a simpler technology.

    In my old age, I really do prefer C. I saw a recent video by Stroustrup discussing an "elegant" program and it really was just all templates with very little logic. I did not find it elegant at all and realized C++ was going in a very different direction to what I really want.

    I "think" I just want the RAII and safety but I am not prepared for any of the other baggage that comes with it. As for CSharp.NET... no thanks. I don't like writing bindings to technology I actually use.

    1. Steve Channell

      native targets

      For a very long time .NET assemblies loaded into the Global Assembly Cache (GAC) have been compiled to native code. Today's .NET native target is more like LLVM than the VM's of old, and C# like Clang.

      If you don't like garbage collection, you wont like the .NET runtime providing GC for you. RAII does not obviate the need to use smart pointers to avoid memory leaks. Porting .NET is no more difficult than porting LLVM

      1. karlkarl Silver badge

        Re: native targets

        You are right that LLVM as one example is pretty complex. It did diverge from its "VM-like" origins a while back. Now it is really just a framework for generating the low level instructions per platform (like GIMPLE-IR/GENERIC in GCC).

        So, yes I would still rather port a simpler compiler. LCC I can make much faster progress on compared to both .NET and LLVM. I still can't decide if GCC or LLVM/Clang is easier to port. But in the end, these compilers don't need to be ported. You can cross compile.

        I do believe .NET is more difficult to port than LLVM. Considering companies like Unity3D were 4 years late to the party after Emscripten (C++/WASM or ASM.js) came out. The .NET framework (and to a lesser extent mono) are big complex things wrangle. Even the JIT and garbage collector has to make big assumptions about a platform.

        Arguably the .NET CLR needs to run "on" the device. LLVM / GCC / etc can cross compile to the native instructions requiring barely any runtime. Even platforms that do support .NET's AOT / GAC (these are actually quite few. I think there is only Intel/ARM. No MIPS, POWER, Sparc64) still require a hefty runtime.

        1. Rich 2 Silver badge

          Re: native targets

          I don’t know much about LLVM but my understanding is that LLVM _is_ a VM. Or rather it defines a VM and compiles the source to that VM. It then takes that VM code and converts it for the target processor.

          The VM code is never intended to be executed directly; it’s just a staging post on the way to the target-specific code

        2. Henry Wertz 1 Gold badge

          Re: native targets

          I'm guessing .NET is much harder to port; LLVM (and GCC) are large and complex, but in terms of actual services they expect from the OS, essentially they open files, process them, and spit out output files. And both are designed with adding new CPUs in mind. Compared to .NET and Java, where they will be using some specific memory allocation support, threading support, and all sorts of OS services (which may not be used by the VM, but some base Java or .NET libraries will expect them so Java/.NET software can potentially use them... of course, libc, libpthread, etc., would be needed for something being compiled with LLVM/GCC to be able to access that functionality too...)

          1. bombastic bob Silver badge
            Devil

            Re: native targets

            And both are designed with adding new CPUs in mind.

            Yes. I have actually DONE it. xmega32e5 is one of them. The gnu tools people are really happy when you give them a quality set of patches for new CPUs. I haven't done LLVM yet but might need to some day, and the same for gcc, if I stay cutting edge with microcontrollers.

            You know, it might be REALLY COOL if Micros~1 were to make their windows build tools compatible with either LLVM _or_ GCC (including MAKE FILES), or maybe BOTH, and then simply made headers and "binutils" tools and 'import' libs available, and THEN switch their build environments to use THEM instead. The LLVM and gcc compilers and binutils very well may have advanced better than Micros~1's compilers and tools, and could be more widely accepted given the additional CPU support.

            They could also submit patches for 'ld' to do Micros~1 stuff, like debug info, resources, manifests, DLL support, whatever. "Developers Developers Developers Developers".

      2. Rich 2 Silver badge

        Re: native targets

        “ RAII does not obviate the need to use smart pointers to avoid memory leaks”

        Smart pointers are a basic building block of RAII principles. At least in C++

      3. Man inna barrel Bronze badge

        Re: native targets

        > RAII does not obviate the need to use smart pointers to avoid memory leaks.

        I am investigating Rust at present, and that seems to do a fine job with non-GC memory management, based on RAII. I have not needed smart pointers yet. Compile time enforcement of object lifetimes and validating references to shared data can lead to some pretty arcane compile time errors, but every time I get one of those, I find I am trying to do something that would probably be unsafe in C++.

        For example, I tried to define a struct containing a reference to an item in a vector. That is definitely unsafe if the vector is mutable, because actual memory locations can vary when the vector is modified, due to re-allocating the underlying data array. I am going to replace the pointer with an index, which is maybe not as neat, but does not suffer from potential memory errors.

    2. Kristian Walsh

      .Net is a specification rather than an implementation, and it does not require a VM-based runtime; the Mono implementation of .Net allows you to compile to native code, with no JIT VM involved. It’s still a GC runtime, but there’s no intermediary bytecode process. https://www.mono-project.com/docs/advanced/aot/

      As for C++, like C#, it brings as little or as much baggage as you want in it. In C++ I really only use RAII and STL containers extensively in my code. I have used templating for generic programming purposes, but I find the extensively templated metaprogramming a little too much along the road of “quick to write; nightmare to maintain” for my taste. I can see how someone from a mathematical background would write code that way, but to me it’s not programming.

    3. Martin Howe

      "... failed attempt at EEE on Java."

      What is EEE, please? Google throws up nothing but pages of irrelevant results :(

      1. karlkarl Silver badge

        Embrace, Extend Extinguish

        An anti-competitive strategy by Microsoft to gain marketshare and push their products. A number of internal memos were leaked which specifically use this name (though I imagine a few other companies did similar).

        So in this case it was against Java. Microsoft made J++ directly in response to Sun Microsystem's Java, got told off by US legal so made J# (as a half-way point) and finally CSharp.NET.

        The damaging part was mainly J++. If they were not stopped in time, they were slowly extending the API with their own incompatible "improvements".

        J# was damage control and CSharp.NET is really just a standard competitor.

        Some more info (including the Java one I outlined):

        https://en.wikipedia.org/wiki/Embrace,_extend,_and_extinguish#Examples_by_Microsoft

        (It is important people remember this (or learn about it) because Microsoft never truly changes and they will be doing the same with Linux and GitHub shortly. Already Microsoft is disabling standard password functionality (for dumb oauth). I'm not sure SSH keys will be an alternative for too long. WSL2 is already starting to be used as a "Linux + drivers + DirectX" kind of product).

        It is fair that you may not agree with what I have wrote (or experienced it) but this is the main reason many guys don't engage with companies like Microsoft. Its up to you to decide how scummy the company is. Just stay safe and don't let them bite you in the butt ;)

        1. Kristian Walsh

          J++ and C# were unrelated development trains, and were internal competitors within Microsoft. J++ initially won, then lost specatularly.

          C# came from a late-1990s project within microsoft called COOL (C-like Object-Oriented Language)

          https://www.theregister.com/2000/09/12/official_microsofts_csharp_is_cool/

          The Common Language Runtime that C# uses is from this project, not the MSJVM one. The bytecode (CIL) used by this runtime is not based on the JVM’s. For a start, it was designed to be multi-language and thus supported features that Java never did (pass-by-value for structs, for instance). CIL has no concessions for an interpreted runtime, whereas the Java bytecode was designed for interpretation or just-in-time compilation.

          C# CLR appears to be a project that had been usurped by J++ within Microsoft, given the mania for all things Java in the 1990s (yeah, I know...). J++ used an incompatible JVM implementation as a form of lock-in, and Sun rightly sued over it.

          Luckily this gave C# the opening, as it was a better language, with a better-designed runtime than Java’s. Also, unlike Sun, Microsoft kept developing C# to add stuff that developers wanted.

          As for the rest of your post, it shows an unfortunate mindset. The world does change. It’s odd how the very people who castigated Microsoft for not adopting Open Source Software are the same ones who now get mad that Microsoft is not adopting Open Source Software. (You might consider how companies like Google leverage FOSS products to build closed software systems before reserving all your ire for Microsoft)

          And the thing in WSL2 is just another Linux kernel fork, whose sources are here: https://github.com/microsoft/WSL2-Linux-Kernel - if you don’t like anything they’ve done with it, fork and patch.

          1. bombastic bob Silver badge
            Trollface

            C# came from a late-1990s project within microsoft called COOL (C-like Object-Oriented Language)

            I was thinking more like a place, with lots of flames, pitchforks, and tormented people screaming...

    4. bombastic bob Silver badge
      Happy

      In my old age, I really do prefer C

      In My Bombastic Opinion, good C++ code looks a LOT like good C code.

  3. fattybacon
    Happy

    Static abstract interface members

    I enjoyed the sample code a little too much for I am nought but a child.

    IP-arse-able

  4. JDX Gold badge

    "perhaps the most important new type system capability since Span<T>"

    Not sure what to make of that, considering I only discovered Span last year after 10 years using C#, and only needed it for one quite narrow edge case. Actually I didn't need it, it made things marginally easier and it was cool so I HAD to use it.

    1. Version 1.0 Silver badge

      Re: "perhaps the most important new type system capability since Span<T>"

      When people say that code is "complex" it just means that they don't fully understand the specific coding environment.

      1. Jimmy2Cows Silver badge

        Re: "perhaps the most important new type system capability since Span<T>"

        You're trolling, right? Must be. Code complexity and environment understanding are definitely not mutually exclusive.

  5. JDX Gold badge

    Cross-platform UI?

    I've recently been using C#/.Net5 for Mac development. It's annoying how many bits of the APIs simply aren't supported even though present. I've been so far limited to console development, though I'm unclear if there is GUI available or not the IDE is nowhere near as good as the proper Windows one.

    A stable, easy to use way to do cross-platform desktop GUI applications would be most welcome. Just an equivalent of Qt/wxWidgets for .Net. Anyone more into this stuff and able to comment what isn#isn't available?

    1. Alan Bourke

      Re: Cross-platform UI?

      That's the intention of .NET MAUI, which is due "real soon now"

      https://docs.microsoft.com/en-us/dotnet/maui/what-is-maui

    2. Anonymous Coward
      Anonymous Coward

      Re: Cross-platform UI?

      Can you people just stop with your cross platform UIs please.

      They don't work right, they don't look right, they don't feel right.

      If you don't have the resource to do a front end per platform just don't support the platform or contract it out.

      If you want to support a proper Mac UI via .net code then Xamarin supports using native UI (just don't go near Xamarin Forms)

      1. Anonymous Coward
        Anonymous Coward

        Re: Cross-platform UI?

        Qt and QML work reasonable well ... as a cross platform UI library. TBH that's all I use them for...

    3. trevorde Silver badge

      Re: Cross-platform UI?

      The only cross-platform UI now is the web. Just remember to test on all browsers, as browser are now the new OS.

      1. Ams627

        Re: Cross-platform UI?

        Well, there's bash.

      2. bombastic bob Silver badge
        Devil

        Re: Cross-platform UI?

        a generic WebKit-based cross-platform frame for HTML-based 'apps' might actually help...

        (I've been kicking this idea around, and it could be written in Python if you don't need real features)

        #!/usr/bin/python

        import sys

        import gtk

        import webkit

        import gobject

        gobject.threads_init()

        window = gtk.Window()

        window.set_default_size(800, 480)

        window.fullscreen()

        window.connect("destroy", lambda a: gtk.main_quit())

        browser = webkit.WebView()

        if len(sys.argv) > 1 : browser.open(sys.argv[1])

        else : browser.open("http://theregister.co.uk/")

        window.add(browser)

        window.show_all()

        gtk.main()

        and then, you wouldn't need complicated installers, monolithic run-times, etc. [other than webkit and python and the other supporting packages that could be loaded with something like pip if you use pythyon. otherwise, an open source C/C++ program compiled for your OS]

        eh, but what do I know...

      3. Loyal Commenter Silver badge
        Trollface

        Re: Cross-platform UI?

        This UI looks funny on Lynx...

  6. picturethis
    Childcatcher

    Time to move on from C#?

    I'm fairly comfortable writing software in C, a little less so in C++ and C#. I've been coding for 30+ years and I don't always feel the need to use the latest whiz-bang feature introduced in the latest iterations of C++ and C# (I only use templates in every other C++ project). But I'm getting a little tired of Microsoft's "3" year development kill lifecycle.

    I've been looking to make the move to Rust over the last couple of months. With this latest C#/memory alloc feature likely leading to disaster, I think I will be accelerating that move. At least for now, I like the idea that MS doesn't completely control the fate of Rust. There seems to be momentum with Rust and I would like to contribute to the momentum. I'll likely never stop coding in C/C++, but I think Rust will be the path forward - at least for cross-platform work and C# will get left behind (for me).

    1. Kristian Walsh

      Re: Time to move on from C#?

      Nobody is forcing you to use this feature, but if you were one of the tiny number of people who really needed this to solve an interoperability problem, you’d be glad of it.

      I put it in the same category as goto and setjmp()/longjmp() which have been in the C language and library since its beginning without me ever using them.

  7. Anonymous Coward
    Anonymous Coward

    The inevitable lifecycle of a language

    Any good programming language gets very popular. Popular languages get lots of development resource to add features to it. Languages with lot of features have a lot of bad features. Languages with bad features end up with bad code. Bad code makes people hate a programming language and look for a replacement...

  8. Anonymous Coward
    Anonymous Coward

    Mixing Xamarin and Xamarin Forms

    Xamarin is not the same as Xamarin Forms. Multiplatform UI is xamarin forms. Xamarin is native api in c#.

  9. mixal11

    Alloc

    Memory alloc functions are useful for interop with native libraries, only edge case, but good to have it covered. I think it can be useful, but still edge case.

  10. RobLang

    I don't think the language is more complex

    In fact, there's less boiler plate with each release. You can write bodyless methods and even a program.cs without a class if need be.

    I'm happy with what MS are doing with .NET. C# was never an attempt at EEE, it was an attempt to stop supporting C++ MFC (good for its time but too tightly constrained to the OS, making OS upgrades more difficult) and huge VB apps that had grown up in the world. It's all open source now and that's not just marketing, you actually get to have input.

    I'm old, have done plenty of memory management and find C#/.NET Core a highly productive language/framework. Much like I did Java. Not needed MAUI and Blazor in anger but they look pretty good solutions to tricky problems.

    The thing MS are crap at is naming things. .NET is a rubbish name (anyone remember trying to Google for that in the early 00s?). Calling the old .NET "Framework" and the new one "Core" makes it sounds like there's an upgrade path, there isn't. Then there is .NET Standard etc etc. And then the numbering goes out the window too. Core 1,2,3... errr (need to avoid confusion with .NET Framework)... 5,6? Entity Framework is just as nonsensical. Whoever is in charge of naming needs to sit down and be talked to sternly over a cup of tea.

  11. Tessier-Ashpool

    3 years

    I don’t know what this 3 year cycle is all about. My trusty old .Net Framework system that gets 20M requests per day, was coded more than a decade ago. I’ve had to lather in newer versions of the framework but it still works fine. They’d better not pull the plug on 4.8 anytime soon, cos we don’t have the manpower to rewrite from scratch.

POST COMMENT House rules

Not a member of The Register? Create a new account here.

  • Enter your comment

  • Add an icon

Anonymous cowards cannot choose their icon

Biting the hand that feeds IT © 1998–2021