What language features do you miss in C#?

Posted by Filip Ekberg on March 1 2013 21 Comments

35563491Every now and then I hear people shout “I really wish C# would have X and Y, it would make my life so much easier”. This makes me think about what features I’d like to see supported in the language. There are multiple factors to take into consideration when thinking about what should be a language feature and not.

If C# would be completely open source and driven by the community we would probably see a lot of pull-requests for new language features. But I’d imagine that many of these features were implemented by someone that felt like the problem solved some in their opinion generic case. This might not actually be the case though. When adding a new language feature, to any language, you need to take into consideration that a big part of the community should benefit from it.

A good example is how language features for asynchronous programming were added in .NET 4.5. But asynchronous programming was possible before this. “All” it really does is adding a nice state-machine and does all the heavy lifting for us. This is something that developers doing asynchronous programming would have to implement over and over again thus making it a perfect candidate to become a language feature.

Mindscape has an article about what F# features every C# developer should lust after which brings up some interesting language features such as:

  • Pattern matching
  • Immutability
  • Object expressions

What language features do you miss in C# and why? Keep in mind that a language feature should target a broad audience! Maybe you’re happy with what is in the language right now?

C# Smorgasbord ebook limited-time offer now only €4.99!

Vote on HN

21 Responses to What language features do you miss in C#?

  1. Samir HafezNo Gravatar says:

    A null-safe dereference operator ( ?. ) would be my pick.
    I really dislike writing something like ‘if(Person != null and Person.Name != null)’.
    I heard that the C# team have considered in the past but found it problematic.
    Maybe due to the uncertainty of an null ‘Person’ or ‘Person.Name’ which can lead to a possible bug being unnoticed.
    Still, I would like to see something like this surface

  2. Adam RalphNo Gravatar says:

    I’m sure there are more useful things that could be added, but I’ve often found myself wanting static extension methods. This could be done with the introduction of a

    the

    keyword, e.g.

    public static Foo(the Console, Bar bar)
    {
        ...
    }

    allowing me to write

    Console.Foo(new Bar());
  3. RichardNo Gravatar says:

    For me it’s multiple inheritance. There are ways of getting close but not quite there.

  4. Adam RalphNo Gravatar says:

    There has been lots of discussion about this over the years. I think it would cause more problems than it would solve. My thoughts are echoed my Marc Gravell

    I’ve never missed it once, not ever. Yes, it [MI] gets complicated, and yes, interfaces do a similar job in many ways – but that isn’t the biggest point: in the general sense, it simply isn’t needed most of the time. Even single inheritance is overused in many cases.

  5. Osama Al ShammariNo Gravatar says:

    Hi,
    Adding event-handlers for controls is really annoying. There is no need for manual implement, it should be automatic like in VB.

  6. Filip EkbergNo Gravatar says:

    I have to agree with Adam. I’ve never seen a good case where multiple inheritance solves the “real” problem.

    Do you have a specific case that you’d like to share?

  7. Adam RalphNo Gravatar says:

    Here’s one I came across today: initializers for auto-properties. E,g,

    public bool Foo { get; set; true; }
  8. JohannesNo Gravatar says:

    Something that I miss quite a lot in C# and other languages is traits that can be found in Scala. Sure you can get around some of it with extension methods but Scala’s type system is quite nice when you learn to leverage it (e.g. the cake pattern).

    http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/

    Cheers,
    Johannes

  9. LosManosNo Gravatar says:

    Non nullable reference.
    It would be awesome for both me and the compiler to know a reference always has a value. Think of all the null reference values that would go away!
    IIRC it can be done today, but only partly, through contracts.

  10. PhylosNo Gravatar says:

    Most of the features that I miss are already available in F#, so thats what I use when features such as discriminated unions and pattern matching would make solving a problem easier. Lets just face it; C# will not get immutability by default, pattern matching, descriminated unions, units of measure, global type-inference, type providers and so on anytime soon. F# 3.0 already has initializers for auto-properties mentioned in a previous comment. So much of what C# programmers crave for is already in F#, that it is really puzzling as to why they don’t attempt to learn the language. I’ve been using it for about 2 years now and I have never had a null-reference exception with it. C# is already a large language and stuffing more and more features into it isn’t really going to help. C# may get some of the features mentioned above but it may take quite a while, as with the new C# async capabilities which F# had the equivalent of in 2007.

  11. LosManosNo Gravatar says:

    Another wish that resurfaced an hour ago is nice syntax for returning more than 1 value from a function.

    Today it is possible with for instance returning a Tuple but the syntax isn’t very nice.
    I would like someting in the lines of

    vars {
    customer,
    project,
    issues
    } = FancySchmancyMethodForGettingLotsOfStuffInOneCall(....);
  12. Pingback: Dew Drop – March 4, 2013 (#1,508) | Alvin Ashcraft's Morning Dew

  13. SteveNo Gravatar says:

    I still miss scoped destructors, so the burden of remembering to dispose resources is kept in the class that manages them, and not left to the consumers to remember.

    And mixins (Scala traits) would be nice as well.

  14. James CurranNo Gravatar says:

    I’d consider this more of a “bug-fix” than an actual new feature, but I’d like to see an expand of the where clause used for generics, so that I can specify that a type parameter has a ctor with certain parameters, or has a certain protected member, or has a certain static member, or is an enum.

    Continuing on ways to make generics more useful (this is largely a .NET framework change rather than a C# change), I’d like to see a series to interfaces to be implemented by all numeric types. e.g., There should be an

         interface IAddable<T> { T Add(T); }

    Int16, Int32, Int64 etc would all implement IAddable which the typical implementation being

       int Add(int other) { return this + other;}

    This would finally let you create a generic based on an int, and be able to ADD something to that int. (There would also need to be an ISubtractable, IMultipliable etc, each action now handled strictly by an operator)

  15. Chris McGrathNo Gravatar says:

    The big ones for me…

    - Default Values for Autoimplemented properties.

    - PropertyChanged for Autoimplemented properties – I’d have a new interface which inherits from INotifyPropertyChanged, and adds one method FirePropertyChanged.

    - Better handling of Null in dot notation, maybe Data..Parent..Description == null (returns true if Data, Data.Parent or Data.Parent.Description is null)

    - Weak reference events being first class citizens – Personally I think all events should default to being weak.

  16. Filip EkbergNo Gravatar says:

    Steve, I couldn’t agree more. Scoped destructors would surely be handy!

    Getting rid of the NullReferences would be on the top of my list as well.

  17. Alan DeanNo Gravatar says:

    I still miss the With operator from VB.COM days. In C# I would like syntax such as:

    var customer = Customer.Load(id)
    with (var address = customer.Address)
    {
        address.Line1 = "123 High Street";
        address.Line2 = "Smallville";
        ...
    }

    rather than the more (IMO) unsightly / repetitive:

    var customer = Customer.Load(id)
    customer.Address.Line1 = "123 High Street";
    customer.Address.Line2 = "Smallville";
  18. Phillip TrelfordNo Gravatar says:

    Steve, Filip,

    On scoped destruction, F# has a use keyword which adds a call to Dispose on the value when the value goes out of scope.
    As mentioned previously, NullReference exceptions are much less common in F# as you have to work hard to create a null reference in the first place.
    When I’m in C# I particularly miss F#’s:
    * Simple class constructor syntax
    * Default values for auto-implemented properties
    * First-class tuple support
    * Type inference
    I have some more detailed examples in a recent blog article: Scrap your Boilerplate.

  19. JoshNo Gravatar says:

    With multiple inheritance, you can get rid of some boiler-plate code for things like INotifyPropertyChanged.

    Personally, I would take either multiple inheritance, or ruby-like mixins. There’s a lot of cool stuff that can be done with that stuff. Sure, it’s dangerous and can be used badly, but you can say that about many of the features in C#. Instead we’re stuck writing the same fricken code everytime we implement IDisposable, or INotifyPropertyChanged, or many other things.

    You can get around of some of this stuff with code templates, but having a first class language feature that supports this would be even better.

  20. PaulNo Gravatar says:

    Nested functions. I hate having to write functions that are global to the class when they could reside within the single function that calls them.

  21. LosManosNo Gravatar says:

    @Paul You are in luck. See http://www.selfelected.com/function-within-a-method-in-c-csharp-dotnet/ for how it is done. If you have an Action example or lambda example, feel free to add a comment.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>