views:

417

answers:

9

I find that using the following:

TreeViewItem i = sender as TreeViewItem;
if(i != null){ ... }

is easier to write and understand than:

if(sender.GetType() == typeof(TreeViewItem)){
    TreeViewItem i = (TreeViewItem)sender;
    ...
}

Are there compelling reasons not to use the first construct?

+7  A: 

Not at all - it gives you the chance to verify that the conversion (cast) was done OK. If you do

TreeViewItem i = (TreeViewItem) sender;

you might get an exception if the cast fails.

Otávio Décio
+4  A: 

"as": good stuff. use it all the time.

if you really want an alternative to manually comparing types try:

  if(person is Employee) { }

reads better yet.

Andrew Robinson
+1  A: 

"as" is faster, but things to bear in mind are:

  • "as" returns a null instead of throwing an exception if that's a problem

  • it won't do custom conversions iirc

  • it doesn't work for reference->value

Edit: "as" definitely is faster (http://www.codeproject.com/KB/cs/csharpcasts.aspx)

Edit2: so basically a speed vs safety decision

annakata
+1  A: 

No, I use it quite a bit. It allows you to avoid InvalidCastExceptions in a clean way.

For example:

TreeViewItem tvItem = sender as TreeViewItem;

if (tvItem != null) return;

// Do stuff

as opposed to:

try
{
    TreeViewItem tvItem = (TreeViewItem)sender;
    // Do stuff.
}
catch (InvalidCastException ex)
{
    // Didn't work, do something about it
    return; // ... or not...
}
Neil Barnwell
Can you think of any reason that "sender" would not be a TreeViewItem other than a bug, in most cases? Bugs *should* raise exceptions IMO.
Jon Skeet
+4  A: 

Your example would be better written as:

if (sender is TreeViewItem) {
    TreeViewItem i = (TreeViewItem)sender;
    ...
}

It is exactly this dual type checking that the as operator can help avoid. So for your cited example, I would say it is definitely a good solution.

However, there are situations where you really do want a cast. If you're expecting a TreeViewItem and want nothing else, casting will ensure an InvalidCastException is thrown if you're given anything else.

Just like in most situations, there is no blanket rule here: use the right tool for the right job.

HTH, Kent

Kent Boogaart
Your alternative to my example is better, thanks!!
Pwninstein
This form can also cause issues when multithreaded as the object can change type between the is cast check and the regular cast.
Cameron MacFarland
+2  A: 

If you want a plain (not nullable) value type, obviously this won't work, eg:

int test = sender as int;

isn't valid, however:

int? test = sender as int?;

is allowed.

Chris Ballard
+6  A: 

Generally speaking, these two snippets are not equivalent. TreeViewItem i = sender as TreeViewItem will yield a correct result even if sender is a grand-grand-child of TreeViewItem, whereas sender.GetType() == typeof(TreeViewItem) will be true only when sender is precisely TreeViewItem and none of its possible subclasses.

Anton Gogolev
+11  A: 

I prefer casts to as in most cases because usually if the type of the object is wrong, that indicates a bug. Bugs should cause exceptions IMO - and an InvalidCastException at exactly the line which performs the cast is a lot clearer than a NullReferenceException much later in the code.

as should be used when it's valid and legal to have been passed a reference to an object of the type that you don't want. That situation does come up, but not as often as normal casting in my experience.

Comparing types using GetType(), however, is very rarely the right solution - it's only appropriate when you want to check for the exact type involved rather than a compatible type.

I've written a significantly longer answer about the "cast vs as" discussion elsewhere.

Jon Skeet
+1  A: 

If getting the wrong type would be a bug, then you should use a cast. The reason for this is that there really is a problem and you should know about it.

If it is possible that the value will be null, and that is not a bug in the system when this happens then use "as". The reason being that you should use "as" any time that getting a null back is acceptable.

Keep in mind that you can't use "as" to convert to value types, because the null value is not acceptable for them. If you have a value type and want to use "as", you will need to use a nullable value type.

When to Use "as" Versus Casting

Brendan Enrick