抽象实现的接口上的C#协方差

Fra*_*erg 3 c# .net-4.0 derived-class covariance c#-4.0

使用C#/ .NET 4.0我希望以下方案是可行的:

interface IA<out TB> where TB : IB { }
interface IB { }

class A<TB> : IA<TB> where TB : IB { }
class B : IB { }


abstract class AbstractA<TB> : IA<TB> where TB : IB { }
class DerivedA<TB> : AbstractA<TB> where TB : IB { }

static void Main(string[] args) {
    var myAB = new A<B>();
    Debug.Assert(myAB is IA<B>); // fine
    Debug.Assert(myAB is IA<IB>); // fine

    var myDerivedAB = new DerivedA<B>();
    Debug.Assert(myDerivedAB is IA<IB>); // fine
    Debug.Assert(myDerivedAB is DerivedA<B>); // fine
    Debug.Assert(myDerivedAB is DerivedA<IB>); // NOT fine        
}
Run Code Online (Sandbox Code Playgroud)

可悲的是,最后的测试失败了,尽管这些类型显然是兼容的.除了测试每个已知的IB实现之外,还有其他方法可以测试吗?

class FirstB : IB { }
class SecondB : IB { }
Debug.Assert(myDerivedAB is DerivedA<FirstB> || myDerivedAB is DerivedA<SecondB>) 
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 5

虽然类型明显兼容

不,他们不是; C#covariance via out仅适用于接口和委托(引用类型,尽管这里很好).它不适用于诸如此类的类Derived<T>.