c# 4.0 - c#协方差抽象实现接口

本文关键字:抽象 实现 接口 方差 | 更新日期: 2023-09-27 18:02:06

使用c#/。我希望下面的场景是可能的:

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        
}
遗憾的是,最后一个测试失败了,尽管这两个类型显然是兼容的。除了测试每个已知的IB实现之外,是否还有其他方法来测试这一点?
class FirstB : IB { }
class SecondB : IB { }
Debug.Assert(myDerivedAB is DerivedA<FirstB> || myDerivedAB is DerivedA<SecondB>) 

c# 4.0 - c#协方差抽象实现接口

尽管类型显然是兼容的

不,他们不是;通过out实现的c#协方差仅适用于接口和委托(引用类型的委托,尽管这里没有问题)。它不适用于诸如Derived<T>之类的类。

可以使用Type object的GetGenericArguments方法:

Type t = myDerivedAB.GetType();
if (t.IsGenericType)
{
    Type[] typeArguments = t.GetGenericArguments();
    Debug.Assert(typeArguments.Length > 0 && typeArguments[0] is IB);
}

通过这个你可以得到myDerivedAB对象的Generic参数,并检查它的类型,或者其他你需要的东西