Direct casting vs 'as' operator?
string s = (string)o;
Use when something should definitely be the other thing.string s = o as string;
Use when something might be the other thing.string s = o.ToString();
Use when you don't care what it is but you just want to use the available string representation.
If you already know what type it can cast to, use a C-style cast:
var o = (string) iKnowThisIsAString;
Note that only with a C-style cast can you perform explicit type coercion.
If you don't know whether it's the desired type and you're going to use it if it is, use as keyword:
var s = o as string;
if (s != null) return s.Replace("_","-");
//or for early return:
if (s==null) return;
Note that as will not call any type conversion operators. It will only be non-null if the object is not null and natively of the specified type.
Use ToString() to get a human-readable string representation of any object, even if it can't cast to string.
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 (e.g. 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.