简体   繁体   中英

Implement a generic class where the definition is on a base interface type but the implementation is on an interface derived from that base?

Is it possible in C# to implement a generic class where the definition is on a base interface type but the implementation is on an interface derived from that base?

I have a base type with core functionality but I need two different variations on that type depending on if my process is working with data data or integer data.

I could kluge my base type to have both data types but I'd rather not.

Example of the problem:

public interface IA {}

public interface IB : IA {}

public class CA : IA {}

public class CB : IB {}

public interface IC<T1> where T1 : IA { }

public class C<TIa> : IC<TIa> where TIa : IA {}

public class Thing
{
    public void Some()
    {
        IA a = new CB(); // fine IB is of type IA
        C<IB> b = new C<IB>(); // fine - obviously

        C<IB> y = new C<IA>(); // shouldn't work - doesn't work
        C<IA> x = new C<IB>(); // even though IB is of type IA this is not acceptable
    }
}

Cannot implicitly convert type 'ClassLibrary1.C<ClassLibrary1.IA>' to     
'ClassLibrary1.C<ClassLibrary1.IB>' // this makes sense

Cannot implicitly convert type 'ClassLibrary1.C<ClassLibrary1.IB>' to 
'ClassLibrary1.C<ClassLibrary1.IA>'  // this should work - IB derives from IA

If I can't implement a generic on derived interfaces then I have a lot of reworking to do on an existing application. Is there some kind of simple way to implement this?

If you declare the type parameter T1 of the interface IC as covariant

public interface IC<out T1> where T1 : IA { }

then you can assign an instance of C<IB> to a variable of type IC<IA>

IC<IA> x = new C<IB>(); // works

But I'm not sure if that answers your question...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM