tags:

views:

202

answers:

9

Possible Duplicate:
Casting: (NewType) vs. Object as NewType

Say for example I have a class called MyObjectType and I want to convert the sender parameter of an event to this type. I would usually go about it by simply doing this:

MyObjectType senderAsMyType = (MyObjectType) sender;

I've recently realised that it can also be done like this:

MyObjectType senderAsMyType = sender as MyObjectType;

Which way is most efficient? So that I can make my code consistent and use one of the ways throughout. Or do they both have pro's and cons? If so please could someone inform me of them.

Thanks again,

+4  A: 

If you wish to avoid any InvalidCastExceptions use

MyObjectType senderAsMyType = sender as MyObjectType;

otherwise use

MyObjectType senderAsMyType = (MyObjectType)sender;

if an InvalidCastException represents a true exceptional situation in your application.

As for performance, I would contend that you would find no discernible difference between the two different kinds of casting. I was interested though so I used Jon Skeet's BenchmarkHelper and achieved results that confirmed my suspicions:

Test:

using System;
using BenchmarkHelper;

class Program
{
    static void Main()
    {
     Object input = "test";
     String output = "test";

     var results = TestSuite.Create("Casting", input, output)
         .Add(cast)
         .Add(asCast)
         .RunTests()
         .ScaleByBest(ScalingMode.VaryDuration);
     results.Display(ResultColumns.NameAndDuration | ResultColumns.Score,
       results.FindBest());
    }

    static String cast(Object o)
    {
     return (String)o;
    }

    static String asCast(Object o)
    {
     return o as String;
    }

}

Output:

============ Casting ============
cast   30.021 1.00
asCast 30.153 1.00
Andrew Hare
+2  A: 

I think this answer will help...

http://stackoverflow.com/questions/2483/casting-newtype-vs-object-as-newtype

Si Keep
Aah sorry, I couldn't find the answer when i searched. Thanks
ThePower
+2  A: 

Basic difference: if sender is not an instance of MyObjectType or one of its subclasses, the first example (direct cast) throws an exception; the second (as operator) returns null.

None of them is plainly better or worse; you should use the one or the other according to the situation you are facing at the moment. If sender is not a MyObjectType what do you want to do? probably, in this case, since it's an event handler, throwing exception is perfectly fine...

Paolo Tedesco
A: 

You should use (MyObjectType) whenever possible, because you will get an exception right away if the cast fails. With as you might get a NullRef-exception anywhere later.
Use as only when you handle a failed cast right afterwards.

tanascius
A: 

They do slightly different things. It depends on what you want.

// Will throw an exception if the cast cannot be made
MyObjectType foo = (MyObjectType)bar;

or

// Will return null if the cast cannot be made
MyObjectType foo = bar as MyObjectType;

Which you use is up to you? If you expect the cast to potentially fail frequently (and you are happy with that) go for as and test for null afterwards, if you expect it never to fail go for (type).

Remember, that if the reference can be null anyway and you need to know that too, test for null before the cast.

Colin Mackay
A: 

Don't worry too much about efficiency, it's better to make the decision based on semantics. Whether one is more efficient than the other will depend heavily on individual circumstance, and how many times you expect it to fail.

A straight cast "(ObjectType)" can fail, and will throw an InvalidCastException.

"as" will not fail with an exception, but instead will return a null object if the cast doesn't work.

If the cast is definitely valid, just do the cast. That way if things go wrong you will get the exception and hopefully be able to solve the problem.

If you aren't certain of the object type, it can be useful to use "as" and just check for null

Simon P Stevens
A: 
MyObjectType senderAsMyType = (MyObjectType) sender;

This will throw an InvalidCastException if sender cannot be cast to MyObjectType.

MyObjectType senderAsMyType = sender as MyObjectType;

senderAsMyType will be null if sender cannot be cast to MyObject. This method cannot be used with value types.

I believe the latter is marginally faster, but the difference is virtually insignificant.

Garry Shutler
I think the speed is very subjective and will be affected by the percentage of cast failures you expect.
Simon P Stevens
A: 

It depends on your expectations of your objects. If the object should be of that type, and you need to access that objects members, use:

MyObjectType senderAsMyType = (MyObjectType) sender;

As stated before, this throws an InvalidCastException for you if it is invalid

If it might be of that type, and you only want to take action if it is, use 'as', and check for null

MyObjectType senderAsMyType = sender as MyObjectType;

if(senderAsMyType != null)
{
    senderAsMyType.MyMethod()
}

However if you are only checking the type, but do not need the object, use the 'is' operator, as this will be cheapest resource-wise

if(sender is MyObjectType)
    //do something
MattH
A: 

From the best practises perspective you should use the as keyword if you expect objects of different types and your code can handle them, e.g.

public void MyFunction(MyObject obj)
{
  obj.DoSomething();
  SpecializedObject specialized = obj as SpecializedObject;
  if(specialized!=null)
  {
    specialized.DoSthSpecial();
  }
}

And use the normal cast when you are sure the type will be what you expect, you just need to cast it because of technical reasons:

XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));
MyObject obj = (MyObject)xmlSerializer.Deserialize(xml);

this way its not only faster, but also doesn't hide errors.

Grzenio