C-style casts versus using the as operator

N

Neil Zanella

Hello,

I would like to ask the following question concerning the C# as operator.
I would like to know whether the difference between using a C-style cast
such as

double x = 0;
float y = (double) x;

and using the as operator is simply that as works on references rather
than on primitive data types. So using the as operator in C# should be
roughly equivalent to casting a pointer type to another in C. I would
like to know though, does anything in particular happen when a concersion
from one reference type to another takes place in C# using the as keyword?
In particular, how does the as keyword work under the hood?

Thanks,

Neil
 
M

Mattias Sjögren

and using the as operator is simply that as works on references rather
than on primitive data types.

No, you can use C-style casts on reference types too.

The difference is that the as operator returns null if the cast fails,
whereas the () cast throws an InvalidCastException.



Mattias
 
H

Helge Jensen

- e as T : yields e as type T if (E is T), null otherwise
- (T)e : yields e as type T if (E is T), exception otherwise

So, you should use "(T)e" where you want immediate failure if E is not
of type t, and "e as T" when you want some behaviour on e, even if it is
not of type T

Example:

class Foo: IComparable {
int i;
public int CompareTo(Object arg0) {
Foo other = arg0 as Foo;
if ( other == null )
return 1;
else
return i - other.i;
}
public override bool Equals(Object arg0) {
Foo other = (Foo)arg0;
return i == other.i;
}
}

please dont do:

public void foo(Object o) {
Foo foo = o as Foo;
if ( foo == null )
throw new ArgumentException("must be instance of Foo", "o");

or, worse:

public void foo(Object o) {
Foo foo = o as Foo;
...
foo.f(x); // throws NullReference if o is not a Foo

Since:

public void foo(Object o) {
Foo foo = (Foo)o;

Gives a much more precise error-path
and using the as operator is simply that as works on references rather
than on primitive data types. So using the as operator in C# should be
roughly equivalent to casting a pointer type to another in C.

No, its like casting pointers with dynamic_cast in _C++_. In C, casts
have no runtime-meaning, they do in C++ (with RTTI...):

C++ C#

dynamic_cast<T>(e) ~ (T)e
dynamic_cast said:
I would
like to know though, does anything in particular happen when a concersion
from one reference type to another takes place in C# using the as keyword?
Nah,

In particular, how does the as keyword work under the hood?

Nothing happens, you can psuedo-code "as" yourself:

public static T as(Object o) {
if ( o is T )
return (T)o;
else
return null;
}
 
D

Daniel O'Connell [C# MVP]

In particular, how does the as keyword work under the hood?

Assuming a straight A to B cast, the primary difference between the two is
the instruction that is used. 'as' and 'is' uses the instruction isinst,
which pushes either the cast value or null onto the stack, while the () cast
uses castclass which throws an exception if the cast fails.

From a language perspective, as is a slightly simpler operator. The ()
casting operator can also perform user defined, implicit value conversions,
and unboxing conversions which gives it more flexibilty(and potentially more
ambiguity).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top