c# casting with is and as

后端 未结 5 976
灰色年华
灰色年华 2021-01-27 13:48

I need some help. It is pretty easy. I have this piece of code, and I would like to discuss if it is correct, or if you suggest a better way to do it. I have an idea about the a

相关标签:
5条回答
  • 2021-01-27 14:04

    I prefer to cast with as and then check for null, this way you can skip the is check. Also, you do not need the elvis operator ?. because you know the object is not null.

    var myObjectA = myObject as ClassA;
    var myObjectB = myObject as ClassB;
    if (myObjectA != null)
    {
        myObjectA.MethodJustInA();
    }
    else if (myObjectB != null)
    {
        myObjectB.MethodJustInB();
        myObjectB.OtherMethodJustInB();
    }
    
    0 讨论(0)
  • 2021-01-27 14:06

    If you're using it this way, you only need to cast it ones:

    var myObjectA = (myObject as ClassA);
    
    if (myObjectA != null)
    {
        myObjectA.MethodJustInA();
    } 
    else
    {
        var myObjectB = (myObject as ClassB);
    
        if (myObjectB != null)
        {
            myObjectB.MethodJustInB();
        }
    }
    

    And in C# 7.0 you can do:

    if (myObject is ClassA myObjectA)
        myObjectA.MethodJustInA();
    else 
        if (myObject is ClassB myObjectB)
            myObjectB.MethodJustInB();
    
    0 讨论(0)
  • 2021-01-27 14:06

    If you are testing for multiple types, then as+null check is more efficient (just one cast, instead of is + casting):

    var a = myObject as ClassA;
    if (a != null)
        a.MethodJustInA();
    var b = myObject as ClassB;
    if (b != null)
        b.MethodJustInB();
    

    In given scenario I'd even make local scope like this

    {
        var obj = myObject as ClassA;
        if (obj != null)
            obj.MethodJustInA();
    }
    {
        var obj = myObject as ClassB;
        if (obj != null)
            obj.MethodJustInB();
    }
    

    { } make it possible to reuse same variable name (easier to copy/paste and, in my oppinion, read).


    I was a bit rushy and haven't thought well about else case (when myObject is ClassA you don't want to cast it as b, etc.). Normally I'd do return after each successful if and corresponding method call. I am not able to construct nice looking if/else if code otherwise.


    Another idea is to use C# 6.0 null-conditional operator:

    (myObject as ClassA)?.MethodJustInA();
    (myObject as ClassB)?.MethodJustInB();
    

    That looks really neat, but it will do unnecessarily casting to B and has side-effect: if ClassB inherits ClassA, then both methods will be called because both casts will success.

    Note: mentioned side effect unfortunately applies to all proposed snippets.

    0 讨论(0)
  • 2021-01-27 14:08

    There are some optimizations possible.

    • If myObject is ClassA, you don't need the soft cast. Instead you can do the cast directly: var myObjectA = (ClassA)myObject;.
    • Since that is the case, and you just call a single method, you don't need to assign a new variable: ((ClassA)myObject)?.MethodJustInA();.
    • And because myObject is ClassA evaluates to false if myObject is null, you don't need to do the check again: ((ClassA)myObject).MethodJustInA();.

    So:

    if (myObject is ClassA)
    {
        ((ClassA)myObject).MethodJustInA();
    }
    else if (myObject is ClassB)
    {
        var myObjectB = (ClassB)myObject;
        myObjectB.MethodJustInB();
        myObjectB.OtherMethodJustInB();
    }
    
    0 讨论(0)
  • 2021-01-27 14:21

    Within those if statements you can just cast your object like this:

    var myObjectB = (ClassB)myObject;
    

    or cast it directly:

    ((ClassB)myObject).MethodJustInB();
    
    0 讨论(0)
提交回复
热议问题