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
{
}
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
.