This will return a list of all extension methods defined in a particular type, including general ones:
public static IEnumerable<KeyValuePair<Type, MethodInfo>> GetExtensionMethodsDefinedInType(this Type t) { if (!t.IsSealed || t.IsGenericType || t.IsNested) return Enumerable.Empty<KeyValuePair<Type, MethodInfo>>(); var methods = t.GetMethods(BindingFlags.Public | BindingFlags.Static) .Where(m => m.IsDefined(typeof(ExtensionAttribute), false)); List<KeyValuePair<Type, MethodInfo>> pairs = new List<KeyValuePair<Type, MethodInfo>>(); foreach (var m in methods) { var parameters = m.GetParameters(); if (parameters.Length > 0) { if (parameters[0].ParameterType.IsGenericParameter) { if (m.ContainsGenericParameters) { var genericParameters = m.GetGenericArguments(); Type genericParam = genericParameters[parameters[0].ParameterType.GenericParameterPosition]; foreach (var constraint in genericParam.GetGenericParameterConstraints()) pairs.Add(new KeyValuePair<Type, MethodInfo>(parameters[0].ParameterType, m)); } } else pairs.Add(new KeyValuePair<Type, MethodInfo>(parameters[0].ParameterType, m)); } } return pairs; }
There is only one problem with this: The return type is not the same as you expect with typeof (..), because it is a generic parameter type. To find all the extension methods for a given type, you will need to compare the GUIDs of all the base types and interfaces of the like type:
public List<MethodInfo> GetExtensionMethodsOf(Type t) { List<MethodInfo> methods = new List<MethodInfo>(); Type cur = t; while (cur != null) { TypeInfo tInfo; if (typeInfo.TryGetValue(cur.GUID, out tInfo)) methods.AddRange(tInfo.ExtensionMethods); foreach (var iface in cur.GetInterfaces()) { if (typeInfo.TryGetValue(iface.GUID, out tInfo)) methods.AddRange(tInfo.ExtensionMethods); } cur = cur.BaseType; } return methods; }
To be complete:
I save a dictionary of objects of type info, which I create when repeating all types of all assemblies:
private Dictionary<Guid, TypeInfo> typeInfo = new Dictionary<Guid, TypeInfo>();
where TypeInfo is defined as:
public class TypeInfo { public TypeInfo() { ExtensionMethods = new List<MethodInfo>(); } public List<ConstructorInfo> Constructors { get; set; } public List<FieldInfo> Fields { get; set; } public List<PropertyInfo> Properties { get; set; } public List<MethodInfo> Methods { get; set; } public List<MethodInfo> ExtensionMethods { get; set; } }
drake7707 Nov 04 '11 at 23:01 2011-11-04 23:01
source share