How to create a constructed generic type without specifying type parameters

If we have something like this:

interface ISomething<U,V> { ... } class Something<U,V> : ISomething<U,V> { ... } 

typeof(ISomething<,>) and typeof(Something<,>) will lead to a definition of "generic type". But if we move on to the type of interface as an interface implemented by the class, it will be a constructed type that is not actually associated with any of its type parameters:

 typeof(Something<,>).GetInterfaces().SingleOrDefault() 

MSDN specifically mentions this. I want to build the same type (built type) ISomething<,> directly (without subclassing and searching for the base type), and I could not find a way to do this.

Additional Information:

I even tried this:

 Type t1 = typeof(ISomething<,>); Type t2 = t1.MakeGenericType(t1.GetGenericArguments()) // Yields a generic type definition Type t3 = typeof(Something<,>).GetInterfaces().SingleOrDefault(); 

In the above code:

t1.Equals(t2) true, but t1.Equals(t3) is false, obviously because t3 built.

Surprisingly, t1.GetGenericArguments()[0].Equals(t3.GetGenericArguments()[0]) is false, although both are open (IsGenericParameter = true), and I could not find the difference in their properties.

And this is why I need to do this: I need a canonical form for storing type objects in a list. Objects sometimes come from base classes / interfaces (e.g. t3 above), and sometimes directly (e.g. t1). I will need to be able to compare them with each other. I cannot save the definition of the generic type (using .GetGenericTypeDefinition() ), because sometimes I will have a partially open constructed generic type (e.g. ISomething), and GetGenericTypeDefinition will give me the type without any type arguments.

The only way I can make canonical types that I thought might work is to check if all the arguments are of the type, and do GetGenericTypeDefinition. Otherwise, save the constructed type.

+7
source share
1 answer

You have all mixed up here. Examine the results of this program and make sure you understand it. Here I alpha renamed the type parameters, so there is no ambiguity due to two things named as U:

 interface I<S, T> { I<S, T> M(); } class C<U, V> : I<U, V> { public I<U, V> M() {return null;} public C<U, V> N() {return null;} } public class MainClass { public static void Main() { var i1 = typeof(I<,>); var i2 = typeof(I<int, int>); var i3 = i2.GetGenericTypeDefinition(); var i4 = i1.GetMethod("M").ReturnType; var c1 = typeof(C<,>); var c2 = typeof(C<int, int>); var c3 = c2.GetGenericTypeDefinition(); var c4 = c1.GetMethod("N").ReturnType; var i5 = c1.GetMethod("M").ReturnType; var i6 = c1.GetInterfaces()[0]; System.Console.WriteLine(i1 == i2); // false -- I<,> is not I<int, int> System.Console.WriteLine(i1 == i3); // true -- I<int,int> decl is I<,> System.Console.WriteLine(i1 == i4); // true -- I<,> is I<S, T> System.Console.WriteLine(i1 == i5); // false -- I<S, T> is not I<U, V> System.Console.WriteLine(i1 == i6); // false -- I<S, T> is not I<U, V> System.Console.WriteLine(c1 == c2); // false -- C<,> is not C<int, int> System.Console.WriteLine(c1 == c3); // true -- C<int,int> decl is C<,> System.Console.WriteLine(c1 == c4); // true -- C<,> is C<U,V> } } 
+4
source

All Articles