public static IEnumerable<Type> GetClosingArguments(this Type type, Type openType)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
if (openType == null)
throw new ArgumentNullException(nameof(openType));
if (!openType.IsOpenGeneric())
throw new ArgumentException("The interface type must be an open generic interface: " + openType.Name);
if (openType.GetTypeInfo().IsInterface)
{
if (!openType.IsOpenGeneric())
throw new ArgumentException("The interface type must be an open generic interface: " + openType.Name);
var interfaceType = type.GetInterface(openType);
if (interfaceType == null)
throw new ArgumentException("The interface type is not implemented by: " + type.Name);
return interfaceType.GetTypeInfo().GetGenericArguments().Where(x => !x.IsGenericParameter);
}
var baseType = type;
while (baseType != null && baseType != typeof(object))
{
var baseTypeInfo = baseType.GetTypeInfo();
if (baseTypeInfo.IsGenericType && baseType.GetGenericTypeDefinition() == openType)
return baseTypeInfo.GetGenericArguments().Where(x => !x.IsGenericParameter);
if (!baseTypeInfo.IsGenericType && baseType == openType)
return baseTypeInfo.GetGenericArguments().Where(x => !x.IsGenericParameter);
baseType = baseTypeInfo.BaseType;
}
throw new ArgumentException("Could not find open type in type: " + type.Name);
}
}