Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# generics - Can I make T be from one of two choices?

Suppose I have the following class hierarchy:

Class A {...}

Class B : A  {...}

Class C : A {...}

What I currently have is

Class D<T> where T : A {...}

but I'd like something of the form

Class D<T> where T in {B,C}

This is due to some odd behavior I'm not responsible for where B and C have common methods which aren't in A, but it would be nice to be able to call them in D on T.

Note: I don't have access to A,B or C to edit them

like image 281
Jean-Bernard Pellerin Avatar asked Jun 21 '10 15:06

Jean-Bernard Pellerin


2 Answers

You need to define an interface for the common methods that are in B and C (lets call it Ibc), make B and C implement this interface, and then you can write:

Class D<T> where T : A, Ibc {...}
like image 178
Grzenio Avatar answered Oct 10 '22 02:10

Grzenio


This isn't directly possible.

As others suggest, you could define an interface and implement it in both B and C.

If this isn't an option (e.g., if these classes are beyond your control), what I might suggest is this: first, start with an abstract class that includes all the functionality you can achieve with any T deriving from A. Then say you have some methods that exist for both B and C that aren't a part of A. In D you can make these abstract methods to be implemented by subclasses:

public abstract class D<T> where T : A
{
    protected T _member;

    public void DoSomethingAllTsCanDo()
    {
        _member.DoSomething();
    }

    public abstract void DoSomethingOnlyBAndCCanDo();
}

Then you can inherit from the base class for each type B and C and override the abstract method(s) to provide the appropriate functionality:

public class DB : D<B>
{
    public override void DoSomethingOnlyBAndCCanDo()
    {
        _member.DoSomethingOnlyBCanDo();
    }
}

public class DC : D<C>
{
    public override void DoSomethingOnlyBAndCCanDo()
    {
        _member.DoSomethingOnlyCCanDo();
    }
}
like image 21
Dan Tao Avatar answered Oct 10 '22 03:10

Dan Tao