DCSIMG
Tip: Casting in C# shortcut extension method - Shimmy on .NET

Tip: Casting in C# shortcut extension method

The C# cast operator (Type)value is pretty verbose.
When you work with COM, extenal APIs, DataSets or other not well-OOPed infrastractures, you often get an expected type as object (i.e. you know the runtime-type of the variable is string, but it's object at compile-time).

Here is an example of many castings in one-line:

IEntity entity = (IEntity)GetObjectById("Customer", 34);
string name = (string)entity.GetField("Name");
int length = name.Length;

Or as a one-liner, you really get confused with the parenthesis:

int len = ((string)((IEntity)GetObjectById("Customer", 34)).GetField("Name")).Length;

With this extension you can make the code a bit more readable:

IEntity entity = GetObjectById("Customer", 34).As<IEntity>();
string name = entity.GetField("Name").As<string>();
int length = name.Length;
 
int len = GetObjectById("Customer", 34).As<IEntity>().
  GetField("Name").As<string>().
  Length;

Here is the extension:

/// <summary>
/// Directly casts an object to a desired type.
/// </summary>
public static T As<T>(this object value)
{
  return (T)value;
}

There is actually nothing sophisticated in this, and cost much more performance (calling an extension method).
But is useful for certain scenarios.

A short performance test shws that using the cast operator is about as twice as faster than the function:

static void Main(string[] args)
{
  Stopwatch watch = Stopwatch.StartNew();
  for (int i = 0; i < 10000000; i++)
  {
    object myInt = 34;
    int theInt = myInt.As<int>();
  }
  watch.Stop();
  long elapsedAs = watch.ElapsedTicks;
 
  watch = Stopwatch.StartNew();
  for (int i = 0; i < 10000000; i++)
  {
    object myInt = 34;
    int theInt = (int)myInt;
  }
  watch.Stop();
  long elapsedCast = watch.ElapsedTicks;
 
  Console.WriteLine("As function took {0} ticks"elapsedAs);
  Console.WriteLine("Cast operator took {0} ticks"elapsedCast);
}
Results: 
As function took 645276 ticks
Cast operator took 294869 ticks
Published Wednesday, April 06, 2011 6:24 PM by Shimmy

Comments

# re: Casting in C# shortcut extension method

Wednesday, April 06, 2011 10:07 PM by Ben

What's wrong with C#'s "as" keyword?

# re: Casting in C# shortcut extension method

Wednesday, April 06, 2011 11:32 PM by Shimmy

@Ben, 'as' is slightly different than (Type) cast.

You can use 'as' in the extension above as well.

To learn about the differences between 'as' and (Type), read blogs.msdn.com/.../what-s-the-difference-between-cast-syntax-and-using-the-code-as-code-operator.aspx.

# re: Casting in C# shortcut extension method

Wednesday, April 06, 2011 11:56 PM by Ben

Thanks!

# re: Casting in C# shortcut extension method

Thursday, April 07, 2011 6:05 PM by Sasha Goldshtein

If you repeat your measurements in Release mode, you will find that there is no difference at all between the two measurements, because (obviously) the "As" method call is inlined. Here's the representative disassembly from both loop bodies [CLR 4.0, x86]:

cmp     dword ptr [esi],offset mscorlib_ni+0x322978

je      002900a9

mov     edx,esi

mov     ecx,5de82978 (MT: System.Int32)

call    clr!JIT_Unbox

However, you are not actually measuring the cost of a cast here, you are measuring the cost of unboxing. Unboxing is more expensive than a cast between reference types.

# re: Casting in C# shortcut extension method

Friday, April 08, 2011 4:29 AM by Shimmy

Sasha, thanks for your comment.

I chose a value-type in purpose to make the overall cost more expensive, so it should be measurable, nevermind.

The real cost is calling the Extension method, the unboxing will be done either way the same (since it's generic).

# re: Casting in C# shortcut extension method

Saturday, April 09, 2011 10:39 PM by Sasha Goldshtein

Again: in Release mode there is no extra cost at all because the method is inlined.

# re: Tip: Casting in C# shortcut extension method

Thursday, August 04, 2011 9:33 PM by hoodaticus

I don't see why calling an extension method would be so expensive.  At the IL level, an instance method call is really just a static method call with the instance reference as the first (hidden) parameter.  Extension methods work the same way.  There should not be a performance hit.  The only slow down should be in the compilation phase.

# re: Tip: Casting in C# shortcut extension method

Friday, August 05, 2011 9:22 PM by Shimmy

I think I meant a "method", calling a method should be more expensive than calling the (type)variable cast operator whatsoever.

# re: Tip: Casting in C# shortcut extension method

Sunday, March 04, 2012 5:31 PM by Shimmy

@Sasha, interesting. Thanks.

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems