Direct casting vs 'as' operator?

后端 未结 16 1819
独厮守ぢ
独厮守ぢ 2020-11-22 01:43

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 str         


        
相关标签:
16条回答
  • 2020-11-22 01:57

    The as keyword is good in asp.net when you use the FindControl method.

    Hyperlink link = this.FindControl("linkid") as Hyperlink;
    if (link != null)
    {
         ...
    }
    

    This means you can operate on the typed variable rather then having to then cast it from object like you would with a direct cast:

    object linkObj = this.FindControl("linkid");
    if (link != null)
    {
         Hyperlink link = (Hyperlink)linkObj;
    }
    

    It's not a huge thing, but it saves lines of code and variable assignment, plus it's more readable

    0 讨论(0)
  • 2020-11-22 02:00

    When trying to get the string representation of anything (of any type) that could potentially be null, I prefer the below line of code. It's compact, it invokes ToString(), and it correctly handles nulls. If o is null, s will contain String.Empty.

    String s = String.Concat(o);
    
    0 讨论(0)
  • 2020-11-22 02:01
    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.

    0 讨论(0)
  • 2020-11-22 02:01

    "(string)o" will result in an InvalidCastException as there's no direct cast.

    "o as string" will result in s being a null reference, rather than an exception being thrown.

    "o.ToString()" isn't a cast of any sort per-se, it's a method that's implemented by object, and thus in one way or another, by every class in .net that "does something" with the instance of the class it's called on and returns a string.

    Don't forget that for converting to string, there's also Convert.ToString(someType instanceOfThatType) where someType is one of a set of types, essentially the frameworks base types.

    0 讨论(0)
  • 2020-11-22 02:02

    All given answers are good, if i might add something: To directly use string's methods and properties (e.g. ToLower) you can't write:

    (string)o.ToLower(); // won't compile
    

    you can only write:

    ((string)o).ToLower();
    

    but you could write instead:

    (o as string).ToLower();
    

    The as option is more readable (at least to my opinion).

    0 讨论(0)
  • 2020-11-22 02:08

    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.

    0 讨论(0)
提交回复
热议问题