Question

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?

Was it helpful?

Solution

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 NullReferenceExceptionmuch 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.

OTHER TIPS

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.

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.

"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.

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.

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.

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...
}

"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

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top