No CS0184 warning for impossible check

55 Views Asked by At

Why does testB in this example not give a "warning CS0184: The given expression is never of the provided ('MyClass2') type" the same way that testA does?

class Program
{
    void Main()
    {
        var a = new MyClass1();
        var b = (IMyInterface)new MyClass1();
        
        //Get a CS0184 Warning on this line
        var testA = a is MyClass2;
        
        //No warning on this line
        var testB = b is MyClass2;
                
    }
}

interface IMyInterface
{
}

class MyClass1 : IMyInterface
{
}

class MyClass2
{
}
1

There are 1 best solutions below

4
Sweeper On BEST ANSWER

Because the type of b is IMyInterface. The compiler does not analyse the code to find the actual runtime type of the object you assigned to b.

It is possible for a variable of type IMyInterface to be is MyClass2. For example, if b refers to an instance of MyClass3:

class MyClass3: MyClass2, IMyInterface {}

Of course, if MyClass2 is sealed, MyClass3 cannot exist, so b can never be is MyClass2 in that case, and you get the warning as expected.

This is also why it is possible to cast an expression of a non-sealed class type to any interface type, e.g.

var a = new MyClass2();
// this compiles, but throws an exception at runtime, of course
var b = (IMyInterface)a;

Even if MyClass2 doesn't implement IMyInterface, at runtime it may be referring to some subclass that does implement IMyInterface.