Tuesday, September 25, 2012

C# features that would be nice to have.

I would like to present some C# features which, in my opinion, could appear in the next versions of the language. This is just my imagination and certainly, I might have not considered some side effects of this stuff :)


  • Readonly local variables.

  • public void Schedule()
    {
      readonly var year = calendar.CurrentYear();
    }
    

    This is something I've seen in Java. In C#, only the class level fields can be readonly. I wouldn't probably use it always for locals. I rather thought of a scenario when some lambda captures the variable and I would like to disallow any writing to that variable.

  • Namespace-scoped generic aliases.

  • Sometimes it's really useful to alias the fluffy generic type name. C# supports creating a local-file alias. For example

    using Pair = KeyValuePair<int, IEnumerable<Tuple<decimal, string>>>;
    

    It would be great if once defined, such alias could be used anywhere in the defining namespace.

  • In SQL-like operator

  • if(variable in (a, b))
    

    Should be neater than

    if(variable == a || variable == b) ...
    

    or

    if(new [] {a, b}.Contains(variable)) ...
    

  • Implicit conversion of equivalent delegates.

  • Delegates with identical signatures could be convertible to each other. Now, for example following code won't compile.

    delegate void ActionHandler();
    MyAction ah = () => { };
    Action a = ah;
    

    The error is:

    Error: cannot convert source type 'ActionHandler' to target type 'System.Action'
    

    This is actually a case that does not occur often though I see no contraindication why this would be impossible. This case is most commonly seen in two built-in delegates: Predicate<T> and Func<T,bool> they represent the same signature though cannot be implicitly converted.

  • Enhanced generic constraints.

  • Constraint for types that allow arithmetic/comparison operations. This could be used with built-in numeric types and for classes that overload +,-,*,/, < etc. operators. For example:

    public class Calculator<T> where T : numeric
    {
      public T Sum(IEnumerable<T> elements)
      {
        T sum = 0;
        foreach(var element i elements)
        {
          sum += element;
        }
      } 
    }
    

    Also, new generic type constraints for enum and a new constraint that could impose constructors with parameters would be nice.

  • Implicit typing for delegates.

  • Compiler won't accept the following declaration:

    var play = (f, d) => Console.Beep(f, d);
    

    Error: Cannot assign lambda expression to an implicitly-typed local variable.
    

    Probably as this is ambiguous between

    Action<int, int> play = (f, d) => Console.Beep(f, d);
    Expression<Action<int, int>> play = (f, d) => Console.Beep(f, d);
    

    It would be nice if the inference mechanism treated every declaration introduced with var keyword always as a delegate type. If an Expression was required then it would have to be declared explicitly.

  • Anonymous types implementing an interface.

  • This is a feature I really hope would be incorporated someday.
    public interface IRepository
    {
      void Add(Item item);
      Item Peek();
    }
    

    It could be possible to implement that interface with the anonymous class like this.

    public IRepository Any()
    {
      return new : IRepository
      {
      Item i = null;
        public void Add(Item item)
        {
          i = item;
        }
        public Item Peek()
        {
          return i;
        }
      }
    }
    

    or:

    public IRepository Any()
    {
      Item i = null;
      return new : IRepository
      {
        Add = (Item item) => i = item;
        Peek = () => i;
      }
    }
    

  • Events that do not throw exception when no handlers are attached.

  • This is how some people try to prevent from NullReferenceException when the invocation list is empty.

    public event EventHandler MyEvent = delegate { };
    

    I would prefer this as a built-in mechanism, of-course for delegates that return void.

No comments:

Post a Comment