Direct casting vs 'as' operator?
Consider the following code:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}
What is the difference between the three types of casting (okay, the 3rd one is not a casting, but you get the intent). Which one should be preferred?
string s = (string)o; // 1
Throws InvalidCastException if o
is not a string
. Otherwise, assigns o
to s
, even if o
is null
.
string s = o as string; // 2
Assigns null
to s
if o
is not a string
or if o
is null
. For this reason, you cannot use it with value types (the operator could never return null
in that case). Otherwise, assigns o
to s
.
string s = o.ToString(); // 3
Causes a NullReferenceException if o
is null
. Assigns whatever o.ToString()
returns to s
, no matter what type o
is.
Use 1 for most conversions - it's simple and straightforward. I tend to almost never use 2 since if something is not the right type, I usually expect an exception to occur. I have only seen a need for this return-null type of functionality with badly designed libraries which use error codes (eg return null = error, instead of using exceptions).
3 is not a cast and is just a method invocation. Use it for when you need the string representation of a non-string object.
It really depends on whether you know if o
is a string and what you want to do with it. If your comment means that o
really really is a string, I'd prefer the straight (string)o
cast - it's unlikely to fail.
The biggest advantage of using the straight cast is that when it fails, you get an InvalidCastException, which tells you pretty much what went wrong.
With the as
operator, if o
isn't a string, s
is set to null
, which is handy if you're unsure and want to test s
:
string s = o as string;
if ( s == null )
{
// well that's not good!
gotoPlanB();
}
However, if you don't perform that test, you'll use s
later and have a NullReferenceException thrown. These tend to be more common and a lot harder to track down once they happens out in the wild, as nearly every line dereferences a variable and may throw one. On the other hand, if you're trying to cast to a value type (any primitive, or structs such as DateTime), you have to use the straight cast - the as
won't work.
In the special case of converting to a string, every object has a ToString
, so your third method may be okay if o
isn't null and you think the ToString
method might do what you want.
上一篇: 为什么C ++编译器不定义运算符==和运算符!=?
下一篇: 直接投射vs'as'运营商?