samy
samy

Reputation: 14972

Can I use recursive constraints to define a generic class

In one of my pet projects I have found myself using generics quite a lot and I'm wondering if it is possible to use recursive constraints in a generic class.

Let's imagine I have the following interface

public interface IAmSpecial {}

and the classes implementing it can each be handled by its own class

public class SpecialHandler<T> where T: IAmSpecial {}

I would like to define a class that is generic over any SpecialHandler

public class SpecialWrapperHandler<T> where T : SpecialHandler<SpecialT> where SpecialT: IAmSpecial
{
    public SpecialWrapperHandler(T t){}
}

which doesn't compile. I can define the SpecialWrapperHandler class with the following signature

public class SpecialWrapperHandler<T> where T : SpecialHandler<IAmSpecial>
{
    public SpecialWrapperHandler(T t){}
}

but then I cannot build it since any SpecialHandler implementation will close the generic value on one implementation of IAmSpecial. Also I cannot declare something like

public class SpecialWrapperHandler<SpecialHandler<T>> where T : IAmSpecial

So is it possible to have a C# construct that recurse generic constraints so I can my SpecialWrapperHandler? If so what construct should I use? And if not, why? A quick read of the generics chapter in the doc doesn't yield many answers...

Upvotes: 2

Views: 477

Answers (1)

Patrick Hofman
Patrick Hofman

Reputation: 157098

Pass in a second type parameter for the handler. In that way you can type both parameters.

Like so:

public class SpecialWrapperHandler<H, T> where H : SpecialHandler<T> where T : IAmSpecial
{
    public SpecialWrapperHandler(T t){}
}

Proof:

public class X : IAmSpecial { }

public class XHandler : SpecialHandler<X> { }

static void Main(string[] args)
{
    X x = new X();
    SpecialWrapperHandler<XHandler, X> v = new SpecialWrapperHandler<XHandler, X>(x);
}

Upvotes: 3

Related Questions