5

Possible Duplicate:
Casting: (NewType) vs. Object as NewType
Casting vs using the 'as' keyword in the CLR

//var gridView = (gridViewRow.NamingContainer as GridView); <-- works too
var gridView = (GridView)gridViewRow.NamingContainer;

My incomplete understanding of this is using as keyword can give null when using a cast () will throw an exception. My goal is to be able to ask myself "which way should I cast?" and know how to answer it.

Community
  • 1
  • 1
Aaron Anodide
  • 16,906
  • 15
  • 62
  • 121
  • 1
    This is a duplicate of many times over like, http://stackoverflow.com/questions/496096/casting-vs-using-the-as-keyword-in-the-clr, or http://stackoverflow.com/questions/2483/casting-newtype-vs-object-as-newtype – Bert Dec 02 '11 at 20:36

6 Answers6

5

It depends, but basically:

If you know and can guarantee that the object is the type you think it is then use ().

If there's a possibility that it could be something else then use as and check for null. In this case you'd have:

var realThing = someObject as MyClass;
if (realThing != null)
{
    ....
}

You can use is to guard the () which would result in:

if (someObject is MyClass)
{
    var realThing = (MyClass)someObject;
    ....
}

But this results in two conversions, rather than the one of as or the straight () cast.

This is where the "it depends" comes in. You'd have to decide on a case by case basis which was more appropriate. You might have coding standards to adhere to as well.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • out of curiosity, what about using "is" operator to guard a use of ()? any different? – Aaron Anodide Dec 02 '11 at 20:09
  • 2
    You shouldn't use "is" to guard, as then you will perform 2 conversions. If you need that functionality, convert with "as" and check for null. – Kyle W Dec 02 '11 at 20:40
3

The question is more of

How do I want my code to deal with a dynamic cast failure?

If you have an implicit / explicit contract that gridViewRow.NamingConainer is in fact a GridView then an () cast is appropriate. If the type is not a GridView it's violated a contract, an exception is thrown and the error will be apparent. However if it's possible that it's not a GridView and you want to proactively handle the case then as is appropriate.

In this case it looks like you do have an implicit contract that it is a GridView and hence I would continue to use (). If you went with as and the contract was broken you'd end up with a NullReferenceException which is not actually the problem. The problem is the type wasn't a GridView as expected and hence InvalidCastException is much more appropriate

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
2

The C# Frequently Asked Questions blog covers this in What's the difference between cast syntax and using the as operator?. There is a discussion of the caveats from Andrew Arnott that you might be interested in too.

Brian Lyttle
  • 14,558
  • 15
  • 68
  • 104
  • Can you summarise the arguments here. If ever the links die there'd be no information in this answer. – ChrisF Dec 02 '11 at 20:30
1

My rule of thumb is that if I know it is the type I am casting it to I use ()s. For example, I would use a direct cast inside a conditional which already checked the type. If I am not sure, I typically use 'as'.

David V
  • 11,531
  • 5
  • 42
  • 66
0

If you know that gridViewRow.NamingContainer is a GridView, yes, use (GridView) to cast. Clearly, the code that follows does not handle null, so if your assumption is wrong, you get an exception either way. Using (GridView) to cast will make the exception useful for you as the programmer, because the exception will show the line that has the bug in its stack trace.

If you do not know whether gridViewRow.NamingContainer is a GridView, you can combine the 'if (gridViewRow.NamingContainer is GridView) { ... (GridView)gridViewRow.NamingContainer ... }' in an 'as' conversion.

0

According to here, the difference lies in how errors in conversion are handled. To summarize:

  • () will throw an exception if the cast is invalid, i.e, if the variable isn't a subclass of the cast.
  • as, on the other hand, will return a null pointer instead, offering slightly better performance at the cost of harder debugging.
Hannele
  • 9,301
  • 6
  • 48
  • 68