为什么在将类转换为未实现的接口时没有编译器错误?

如果我尝试从类到接口的无效转换,那么编译器不会抱怨(错误发生在运行时); 但是,如果我尝试对抽象类进行类似的转换,它抱怨。

class Program { abstract class aBaz { public abstract int A { get; } } interface IBar { int B { get; } } class Foo { public int C { get; } } static void Main() { Foo foo = new Foo(); // compiler error, as expected, since Foo doesn't inherit aBaz aBaz baz = (aBaz)foo; // no compiler error, even though Foo doesn't implement IBar IBar bar = (IBar)foo; } } 

为什么编译器拒绝从FooIBar的转换 ,当它(看似?)无效时? 或者,翻转问题,如果编译器允许对接口IBar进行 “无效” 转换 ,为什么不允许对抽象类aBaz进行类似的“无效” 转换

你需要了解.Net的inheritance系统,看看为什么这是有意义的。 在.Net中,类可以仅从一个基类inheritance,但可以实现任意数量的接口。

 class Program { abstract class aBaz { public abstract int A { get; } } interface IBar { int B { get; } } class Foo { public int C { get; } } class BarableFoo : Foo, IBar { public int C { get; } } static void Main() { // This is why the compiler doesn't error on the later cast Foo foo = new BarableFoo(); // compiler error: aBaz is a class and the compiler knows that // Foo is not a _subclass_ of aBaz. aBaz baz = (aBaz)foo; // no compiler error: the class Foo does not implement IBar, however at runtime // this instance, "foo", might be a subclass of Foo that _implements_ IBar. // This is perfectly valid, and succeeds at runtime. IBar bar = (IBar)foo; // On the other hand... foo = new Foo(); // This fails at runtime as expected. bar = (IBar)foo; } } 

在问题中极其简单的原始示例中,似乎编译器可以检测到foo的这个实例永远不会被转换为IBar,但这更像是一个“很好的”警告,而不是语言正确性问题。

演员的全部意义是抑制编译器错误。
(例如,如果你知道foo实际上是一个实现接口的子类型的实例)

如果编译器可以certificate演员阵容不可能成功,那么它仍然会出错。 (例如,如果您转换为不在其层次结构中的类)

并且为了表明编译器不是愚蠢的,当编译时编译失败时会出现这样的情况:如果编译器可以certificate没有其他类可以从类派生,它将在编译时失败转换为接口:

 sealed class NoBar { } struct NoBarValue { } IBar noBar = (IBar)(new NoBar()); // fails at compile time IBar noBarValue = (IBar)(new NoBarValue()); // fails at compile time 

在第一种情况下( NoBar )类被明确地密封(因此没有派生类可以实现IFoo)并且编译器知道它本身不实现IBar – 因此在编译时可能失败。 第二种情况( NoBarValue )类似,唯一的区别是值类型(struct)被隐式密封。