Trying to find out if a provided Type is of a given generic type (with any generic types inside)
Let me Explain:
bool IsOfGenericType(Type baseType, Type sampleType)
{
/// ...
}
Such that:
IsOfGenericType(typeof(Dictionary<,>), typeof(Dictionary<string, int>)); // True
IsOfGenericType(typeof(IDictionary<,>), typeof(Dictionary<string, int>)); // True
IsOfGenericType(typeof(IList<>), typeof(Dictionary<string,int>)); // False
However, I played with some reflection in the intermediate window, here were my results:
typeof(Dictionary<,>) is typeof(Dictionary<string,int>)
Type expected
typeof(Dictionary<string,int>) is typeof(Dictionary<string,int>)
Type expected
typeof(Dictionary<string,int>).IsAssignableFrom(typeof(Dictionary<,>))
false
typeof(Dictionary<string,int>).IsSubclassOf(typeof(Dictionary<,>))
false
typeof(Dictionary<string,int>).IsInstanceOfType(typeof(Dictionary<,>))
false
typeof(Dictionary<,>).IsInstanceOfType(typeof(Dictionary<string,int>))
false
typeof(Dictionary<,>).IsAssignableFrom(typeof(Dictionary<string,int>))
false
typeof(Dictionary<,>).IsSubclassOf(typeof(Dictionary<string,int>))
false
typeof(Dictionary<,>) is typeof(Dictionary<string,int>)
Type expected
typeof(Dictionary<string,int>) is typeof(Dictionary<string,int>)
Type expected
typeof(Dictionary<string,int>).IsAssignableFrom(typeof(Dictionary<,>))
false
typeof(Dictionary<string,int>).IsSubclassOf(typeof(Dictionary<,>))
false
typeof(Dictionary<string,int>).IsInstanceOfType(typeof(Dictionary<,>))
false
typeof(Dictionary<,>).IsInstanceOfType(typeof(Dictionary<string,int>))
false
typeof(Dictionary<,>).IsAssignableFrom(typeof(Dictionary<string,int>))
false
typeof(Dictionary<,>).IsSubclassOf(typeof(Dictionary<string,int>))
false
So now I’m at a loss because when you look at the base.Name on typeof(Dictionary) you get
Dictionary`2
Which is the same as typeof(Dictionary<,>).Name
At first I thought that this should work:
The GetGenericTypeDefinition method returns a version of the type without specified generic parameters. For example for type
List<int>it will give youList<>.But, unfortunately, this doesn’t quite work, because the generic type definitions aren’t assignable from each other (because they are not real types that you could use anywhere in your code). The
IsAssignableFrommethod works only for actual types. This means that we need to make additional step and specify some type parameters back to the generic type definitions and then we can check whether they are assignable.You can fill the type parameters with
System.Objectand then compare them:This turns the generic type definition back to a normal type, so you’ll get for example
IList<Object>andList<Object>which can be tested easily usingIsAssignableFrom.[There are still some limitations – see comments]