How to specify a generic type as a constraint in a generic method

I have a generic class:

class MyGenericClass<T> { }

      

On the other hand, I have an aggregator class that I use to get singleton instances MyGenericClass

and derived classes, where each instance is identified by a specific class type and parameter type. That is, it MyGenericClass<int>

differs from MyGenericClass<string>

and from MyDerivedGenericClass<int>

; there is one copy for each of them.

The main member of an aggregator is a method GetInstanceOf

that returns a singleton instance of the specified type. The problem is that I want to specify the type as a generic parameter, but I cannot find a way to create a constraint of type "the parameter must be of type MyGenericClass (or derived) with any parameter type". Long story short, I want something like this:

T GetInstanceOf<T>() where T : MyGenericClass<> //This does not compile

      

So what can I do? Can such a limitation be specified?

EDIT: The method GetInstanceOf<T>

does indeed return T, not void.

+2


source to share


5 answers


You probably want to create an interface and implement your generic class. MyGenericClass <INT> and MyGenericClass <string> are considered completely different classes by the .NET compiler.

This will allow you to do something like this:

void GetInstanceOf<T>() where T : IMyGenericClass

      

You can also use a generic base class:

void GetInstanceOf<T>() where T : MyGenericClassBase

      



Finally, you can try adding a second type to your method:

void GetInstanceOf<T, U>() where T: MyGenericClassBase<U>

      

(I'm not sure about this last one ... I don't have a compiler to test it)

See: http://msdn.microsoft.com/en-us/library/aa479859.aspx#fundamentals_topic12

+6


source


interface IMyGenericBase { /* ... */ }

class MyGenericClass<T> : IMyGenericBase { /* ... */ }

class MyDerivedGenericClass<T> : MyGenericClass<T> { /* ... */ }

T GetInstanceOf<T>() where T : IMyGenericBase { /* ... */ }

      



+4


source


I think you are making this much more difficult than necessary. Take a step back and solve the real problem instead of trying to solve some completely unnecessary constraint problem. It seems very simple:

MyGenericClass<T> GetInstanceOfMyGenericClass<T>() 
{ 
    return MyGenericClass<T>.GetSingleton(); 
}

      

You want to MyGenericClass<int>

, say GetInstanceOfMyGenericClass<int>()

, do. Why bother with all the restrictions if you don't need it?

+2


source


If it were me, I would most likely create an interface, have "MyGenericClass" implement that interface, and then use the interface in the "where" of your method signature.

+1


source


I agree with most of the posts here - providing an interface is generally the best approach.

However, if MyGenericClass<T>

it turns out to be a class defined outside of your control, another option is to do:

 void GetInstanceOf<T, U>() where T : MyGenericClass<U>

      

Unfortunately this requires your caller to supply the generic type MyGenericClass as well, but it will compile and run correctly if you cannot change "MyGenericClass".

+1


source







All Articles