using System.Collections.Generic;
using System.Runtime.CompilerServices;
public static class TypeExtensions
public static MethodInfo GetExtensionMethod(this Type type, string name)
return type.GetExtensionMethods().Single(m => m.Name.Equals(name, StringComparison.Ordinal));
public static IEnumerable<MethodInfo> GetExtensionMethods(this Type type)
return type.GetExtensionMethods(type.Assembly);
public static IEnumerable<MethodInfo> GetExtensionMethods(this Type type, Assembly assembly)
return type.GetExtensionMethods(new Assembly[] { assembly });
public static IEnumerable<MethodInfo> GetExtensionMethods(this Type type, IEnumerable<Assembly> assemblies)
const BindingFlags BINDING_FLAGS = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
.SelectMany(assembly => assembly.GetTypes().Where(t => t.IsExtensionMethodClass())
.SelectMany(t => t.GetMethods(BINDING_FLAGS))
.Where(m => m.IsExtensionMethodForType(type)));
public static bool IsGenericTypeAssignableFrom(this Type type, Type assignedType)
if (assignedType.IsGenericType &&
assignedType.GetGenericTypeDefinition().Equals(type))
foreach (var interfaceType in assignedType.GetInterfaces())
if (interfaceType.IsGenericType &&
interfaceType.GetGenericTypeDefinition().Equals(type))
if (default(Type) == assignedType.BaseType)
return type.IsGenericTypeAssignableFrom(assignedType.BaseType);
public static bool IsExtensionMethodClass(this Type type)
return type.IsSealed && !type.IsGenericType && type.IsDefined(typeof(ExtensionAttribute), false);
public static class MethodBaseExtensions
public static bool IsExtensionMethodForType(this MethodBase method, Type type)
if (!method.IsDefined(typeof(ExtensionAttribute), false))
if (1 > method.GetParameters().Count())
var extendedType = method.GetParameters().First().ParameterType;
if (extendedType.IsGenericType)
return extendedType.IsGenericTypeAssignableFrom(type);
return extendedType.IsAssignableFrom(type);