Why not simply close the open generic type and see if that is assingable from the closed type? The catch would be that closing it with the same arguments might not be valid so you'd need to catch that
private static bool OpenGenericIsAssignableFrom(
Type openGenericType,
Type typeToCheck)
{
if (!openGenericType.IsGenericType || typeToCheck == null) return false;
if(typeToCheck.IsGenericType)
{
var typeArgs = typeToCheck.GetGenericArguments();
if (typeArgs.Length == openGenericType.GetGenericArguments().Length)
{
try
{
var closed = openGenericType.MakeGenericType(typeArgs);
return closed.IsAssignableFrom(typeToCheck);
}
catch
{
//violated type contraints
return false
}
}
}
else
{
return OpenGenericIsAssignableFrom(openGenericType, typeToCheck.BaseType)
|| typeToCheck.GetInterfaces()
.Any(i=> OpenGenericIsAssignableFrom(openGenericType,i));
}
}