James Michael Hare

...hare-brained ideas from the realm of software development...
posts - 166 , comments - 1431 , trackbacks - 0

My Links


Welcome to my blog! I'm a Sr. Software Development Engineer in the Seattle area, who has been performing C++/C#/Java development for over 20 years, but have definitely learned that there is always more to learn!

All thoughts and opinions expressed in my blog and my comments are my own and do not represent the thoughts of my employer.

Blogs I Read

Follow BlkRabbitCoder on Twitter

Tag Cloud

Article Categories


Post Categories



Little Wonders

Little Wonders


C# 5.0 and Beyond - My Wish List

I apologize in advance to those waiting for part 2 of the Windows Services post I did last week.  I will have a follow-up post next week, this week at work has just been crazy and I haven’t had as much time to devote to the code examples as I’d like to polish it.  So instead I thought I’d throw a quick post out on what I’d like to see in the future versions of C#.

A lot of folks are posting things they would like to see in C# 5.0 and beyond.  There’s a great list on Stack Overflow (here) and a great post by Abhishek Sur (here).  So I thought I’d throw my two cents into the arena and say what I’d like to see.  C# 4.0 is already such a fine and robust language that it’s hard to think of great new features.  In many ways the language spoils us to where going back to an older language like C++ is downright painful!

That said, there are a few things I could think of that would help spoil developers (especially me) even more, so here they are.

Null Safe Dereferencing (-> operator)

The null-coalescing operator is great for substituting for null, such as:

   1: // will return the string if non-null or empty string if null
   2: return someString ?? string.Empty;

But it doesn’t work if you’re trying to access a property from a potentially null value like this:

   1: // we have to use ? : here because ?? won't work since we want Length and
   2: // not just myString itself.
   3: return myString != null ? myString.Length : 0;

Some folks have suggested a new operator such as ??? to shorten this, like:

   1: return someString.Length ??? 0;

However, the ??? wouldn’t be quite as nice for long chains.  There was a great post on With() and Return() extension methods (here) that I’ve liked so much I’ve added something similar to my own code-base.  Basically instead of writing:

   1: if (employee != null && employee.Addresses != null && employee.Addresses.Length > 0)

You could write:

   1: if (employee.With(e => e.Addresses).Return(a => a.Length, 0))

Where With() is used for null safe collapsing (returns null if item evaluated is null) and Return() is used for null safe evaluation and substitution (returns default value if item evaluated is null).

I was thinking we could combine these and have a null safe dereferencer.  Possibly bring in the C++ pointer dereferencer operator (->).  This would dereference the reference type if it’s non-null or collapse to the default of the evaluator (0 for primitives, null for references).  This would only be applicable to reference types (like With()):

   1: if (employee->Addresses->Length > 0)

Here, if employee is nul the employee->Addresses will return null, and that null will be passed to Addresses->Length which will evaluate to the default(int) which will be zero.

IUsable Interface

I love using IDisposable in using blocks, it makes it so nice for ensuring that resources are cleaned up no matter if the scope is exited normally or by an exception.  One thing I’d like to change though is allowing using to support a new interface as well (call it IUsable for example). 

Why?  Well, there are a lot of purists who say IDisposable should only be used on objects that have resources to free, and if you read the MSDN description of IDisposable, they have a point.  So I propose a new interface IUsable that can be used to fill the void for folks who want to scope a set of operations with the using block.

For example, I have created wrappers for PerformanceCounters to make them easier to use that return a MeasurementBlock struct that is an IDisposable.  In this way it will start a Stopwatch on construction and stop the Stopwatch and update the PerformanceCounter instance at the end of the using.  And there are many more applications. 

In my mind, IUsable would look like:

   1: // An interface that supports using a type in a using block with 
   2: // methods that will be called when the using block is entered and exited.
   3: public interface IUsable
   4: {
   5:     // Called at entry into the using block
   6:     void Begin();
   8:     // Called at exit from the using block
   9:     void End();
  10: }

This interface could either be directly supported by using or you could have an adapter such as:

   1: //  a wrapper to automatically up-promote an IUsable to an IDisposable
   2: public struct DisposingUsable : IDisposable
   3: {
   4:     // handle to the IUsable instance
   5:     private IUsable _usable;
   7:     // constructs a disposable from the usable, should be null-safe like using block is.
   8:     public DisposingUsable(IUsable usable)
   9:     {
  10:         _usable = usable;
  12:         if (_usable != null) _usable.Begin();
  13:     }
  15:     // clean up instance of usable, should be null-safe like using is
  16:     public void Dispose()
  17:     {
  18:         if (_usable != null) _usable.End();
  19:     }
  20: }

Unfortunately, since you can’t define a conversion from an interface to a type, I can’t make this seamless today, so I’d also like…

Ability to Define Conversions From Interface to Concrete Types

As the last point mentioned, you can’t define a conversion from an interface to a type or you get a compiler error, let’s say we took the DisposingUsable above and wanted to make it seamless so we didn’t have to explicitly construct, we could define:

   1: //  a wrapper to automatically up-promote an IUsable to an IDisposable
   2: public struct DisposingUsable : IDisposable
   3: {
   4:     // ... all the stuff defined before
   6:     // can't do this in C# currently because IUsable is an interface.
   7:     public static implicit operator DisposingUsable(IUsable usable)
   8:     {
   9:         return new DisposingUsable(usable);
  10:     }
  11: }

This would let us be able to do this in today’s environment:

   1: IUsable performanceCounter = new AutoCounter(...); // my performance counter wrapper
   3: // will implicitly convert from IUsable to IDisposable by wrapping
   4: // in DisposingUsable struct
   5: using (performanceCounter)
   6: {
   7:     // do stuff to measure with performance counter
   8: }

If we could have the ability to define conversions from an interface to a solid type, I could just have my utility class above and be happy with my IUsable interface (though it may still cause purists some grief).

Static Extension Methods and Extension Properties

I agree with the folks who clamor for additional extension capabilities.  For instance, we love string.IsNullOrEmpty() but what if you wanted to define a new method like string.NullSafeLength() where it could be applied on a string to get the Length if it is non-null or zero if null.

Unfortunately, since it’s a static method, you would have to define this in your own utility class, something like StringUtility.NullSafeLength() which makes it less intuitive.  It would be nice if you could add static extension methods to a class.  Perhaps instead of using the this keyword for a parameter, using static instead like:

   1: public static class StringExtensions
   2: {
   3:     public static int NullSafeLength(static string, string someString)
   4:     {
   5:         return someString != null ? someString.Length : 0;
   6:     }
   7: }

Or perhaps using some sort of generic syntax like <static string>.  At any rate, something like this would enable you to use this extension method as if it were a static member of the type:

   1: if (string.NullSafeLength(myString) > 5)

Yes, we could apply an instance NullSafeLength() extension method, but then you’re calling an extension method from a null reference which is frowned upon by many, so a way to do static extension methods would be ideal.

Along the same vein as static extension methods, extension properties would be nice.  You could apply the same this keyword to the property declaration, possibly in the definition of the get and set such as:

   1: public static class StringExtensions
   2: {
   3:     public static int IsFrontPadded
   4:     {
   5:         get (this string someString)
   6:         {
   7:             ...
   8:         }
  10:         set (this string someString)
  11:         {
  12:             ...
  13:         }
  14:     }
  15: }

Scoped Lifetime of Reference Types

It would be nice to be able to define a scoped lifetime of a reference type, much like the boost::scoped_ptr in the C++ boost library.  This special reference wrapper would hold the reference and destroy it when it passes out of scope, and would disallow assigning or passing the reference. 

Yes, it has limited application, but it would also make for some much better performing code in places where you have a type with a limited lifetime but don’t want to use struct due to size or performance constraints. 

This could possibly be achieved by wrapping the reference in a special struct that has a unique operator . overload which allows dereferencing the members of the wrapped reference, but gives no way to pull the wrapped reference back out.  You could use a specialized operator such as ^ to represent the scoped type and do the wrapping and collection behind the scenes.  Like:

   1: if (receivedText.Length > 0)
   2: {
   3:     ^Message msg = new Message(receivedText);
   5:     ... // in body here, can only dereference msg, you can't copy reference.
   7:     // scope ends here so msg is immediately collected.
   8: }


So that’s the things I’d like to see in C# 5.0 or beyond.  What’s your thoughts?


 Technorati Tags: ,,,,


Print | posted on Friday, October 1, 2010 10:15 AM | Filed Under [ My Blog C# Software .NET vNext ]

Powered by: