Using IsAssignableFrom with 'open' generic types
From the answer to another question:
public static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
var interfaceTypes = givenType.GetInterfaces();
foreach (var it in interfaceTypes)
{
if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
return true;
}
if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
return true;
Type baseType = givenType.BaseType;
if (baseType == null) return false;
return IsAssignableToGenericType(baseType, genericType);
}
IsAssignableFrom when interface has generics, but not the implementation
I think you have to call GetInterfaces()
from your StringMapper and test each one for IsGenericType
. Last but not least get the open type (IMapper<,>
) of each generic one by calling GetGenericTypeDefinition()
and test if it matches typeof(IMapper<,>)
.
That's all you can do. But be aware, if the class inherits from another base class which also implements some interfaces, these won't be listed. In that case you have to recursevly run down through the BaseType
properties and do the above down till the BaseType
is null.
IsAssignableFrom on GenericType
There is not an inheritance relationship between a generic type definition and a closed generic type. Therefore, IsAssignableFrom
will not work.
However, I use this little extension method to achieve what your after:
public static bool IsGenericTypeOf(this Type t, Type genericDefinition)
{
Type[] parameters = null;
return IsGenericTypeOf(t, genericDefinition, out parameters);
}
public static bool IsGenericTypeOf(this Type t, Type genericDefinition, out Type[] genericParameters)
{
genericParameters = new Type[] { };
if (!genericDefinition.IsGenericType)
{
return false;
}
var isMatch = t.IsGenericType && t.GetGenericTypeDefinition() == genericDefinition.GetGenericTypeDefinition();
if (!isMatch && t.BaseType != null)
{
isMatch = IsGenericTypeOf(t.BaseType, genericDefinition, out genericParameters);
}
if (!isMatch && genericDefinition.IsInterface && t.GetInterfaces().Any())
{
foreach (var i in t.GetInterfaces())
{
if (i.IsGenericTypeOf(genericDefinition, out genericParameters))
{
isMatch = true;
break;
}
}
}
if (isMatch && !genericParameters.Any())
{
genericParameters = t.GetGenericArguments();
}
return isMatch;
}
With sample usage:
Nullable<int> value = 9;
Assert.IsTrue(value.GetType().IsGenericTypeOf(typeof(Nullable<>)));
Determine if object is an instance of a generic base class, any generic type
The problem is that DrevidedC1
is not a sublcass of Class1<T>
, it's a subclass of Class1<int>
. Make sure you understand this subtle diference; Class1<T>
is a open type (T
can be anything, it hasn't been set) while DerivedC1
extends a closed type Class1<int>
(it's not open in T
anymore, T
is set to int
and only int
). So when you do the following:
typeof(DerivedC1).IsSubclassOf(typeof(Class1<>))
The answer is evidently false
.
What you need to do is check if the generic type definition of DerivedC1
's base type (think of it as the corresponding open generic type of Class1<int>
) equals Class1<T>
which it clearly does.
The correct code is therefore:
typeof(DerivedC1).BaseType.GetGenericTypeDefinition() == typeof(Class1<>));
Or better yet, as Matías Fidemraizer states in his answer:
typeof(DerivedC1).BaseType.GetGenericTypeDefinition().IsAssignableFrom(typeof(Class1<>)));
IDictionary`2 not assignable from Dictionary`2
You need to search the type's interfaces and check if any are an instantiation of the IDictionary<K, V>
interface:
bool isDict = type.GetInterfaces().Any(it => it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IDictionary<,>));
Related Topics
Checking If a String Array Contains a Value, and If So, Getting Its Position
.Contains() on a List of Custom Class Objects
Getproperties() to Return All Properties for an Interface Inheritance Hierarchy
Test If a Website Is Alive from a C# Application
Which Is the Correct C# Infinite Loop, for (;;) or While (True)
How to Calculate the Sum of the Datatable Column in ASP.NET
Can a Class Library Have an App.Config File
Get the Property, as a String, from an Expression<Func<Tmodel,Tproperty>>
Async/Await Different Thread Id
Calculated Column in Ef Code First
How to Generate a Cryptographically Secure Pseudorandom Number in C#
Use of SQLparameter in SQL Like Clause Not Working
Serialize a Bitmap in C#/.Net to Xml
What Is the Fastest Way to Convert a Float[] to a Byte[]
It Is Possible to Copy All the Properties of a Certain Control? (C# Window Forms)
How to Deserialize a Unix Timestamp (Μs) to a Datetime from JSON