TAGS :Viewed: 4 - Published at: a few seconds ago

[ Generic type arguments inside generic constraints ]

I want to create a class that has a generic type argument which has a constraints to be a subclass of another generic class.

Example:

public class SomeGeneric<T> where T : new()
{
    T CreateItem() => new T();
}

This class I want to create. Note: I do not want client of this class to specify the inner type argument twice:

public class TheClass<TGeneric> where TGeneric : SomeGeneric<T>, new()
{
    public T Item {get; private set;}
    public void TheClass
    {
        var instance = new TGeneric(); // this is possible because of the new() restriction
        Item = instance.CreateItem();
    }
}

This could then be used as follows:

class AnotherClass
{

}

class Client : TheClass<SomeGeneric<AnotherClass>>
{
    public void SomeMethod()
    {
        var theInstanceOfAnotherClass = this.Item;
        // Do stuff with it
    }
}

As far as I can tell, this is not possible since it complains on this line that T is not known:

public class TheClass<TGeneric> where TGeneric : SomeGeneric<T>, new()

The workaround would be to do as follows:

public class TheClass<T, TGeneric> where TGeneric : SomeGeneric<T>, new()

But that would mean that the client has to do this:

public class Client : TheClass<AnotherClass, SomeGeneric<AnotherClass>>

I want to avoid duplicating the inner type argument. Is this possible?

Answer 1


I don't think this is possible. This question addresses the same situation.

This blurb from MSDN also states that it's not allowed, unlike in C++. I'm not sure if there's a reason for this limitation.

In C#, a generic type parameter cannot itself be a generic, although constructed types can be used as generics. C++ does allow template parameters.

I think you will have to rework your class in some way to use a generic object, or else just live with the duplicate type argument.