Mark Carpenter
Mark Carpenter

Reputation: 17775

Are there compelling reasons AGAINST using the C# keyword "as"?

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?

Upvotes: 7

Views: 564

Answers (9)

Kent Boogaart
Kent Boogaart

Reputation: 178630

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.

Upvotes: 4

Brendan Enrick
Brendan Enrick

Reputation: 4297

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

Upvotes: 1

annakata
annakata

Reputation: 75794

"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

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500055

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.

Upvotes: 12

Otávio Décio
Otávio Décio

Reputation: 74250

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.

Upvotes: 7

Anton Gogolev
Anton Gogolev

Reputation: 115711

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.

Upvotes: 6

Chris Ballard
Chris Ballard

Reputation: 3769

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.

Upvotes: 2

Neil Barnwell
Neil Barnwell

Reputation: 42105

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

Upvotes: 1

andleer
andleer

Reputation: 22568

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

Upvotes: 4

Related Questions