开发者

C# covariance on abstractly implemented interface

Using C#/.NET 4.0 I was hoping the following scenario would be possible:

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        
}

Sadly the last test fails, although the types clearly are compatible. Would there be another way to test this, other than testing for every known implementation of IB?

class FirstB : IB { }
class SecondB : IB { 开发者_JS百科}
Debug.Assert(myDerivedAB is DerivedA<FirstB> || myDerivedAB is DerivedA<SecondB>) 


although the types clearly are compatible

No they aren't; C# covariance via out applies only to interfaces and delegates (of reference-types, although that is fine here). It does not apply to classes such as Derived<T>.


You can use GetGenericArguments method of Type object:

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

By this you can get the Generic parameter of the myDerivedAB object, and check its type, or something else you need.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜