using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices;
namespace ConsoleApp1 { public class Animal { public int ID { get; set; } public string Name { get; set; } }
public static class Extension { public static string GetStringValue(this int v) { return "我是Int类型:" + v; }
public static string GetStringValue(this string v) { return "我是String类型:" + v; } } class Program { static void Main(string[] args) { Animal a = new Animal() { ID = 1, Name = "mimi" };
var properities = typeof(Animal).GetProperties(); var thisassembly = typeof(Animal).Assembly; for (int i = 0; i < properities.Length; i++) { var v = properities[i].GetValue(a); foreach (var m in GetExtensionMethods(thisassembly, v.GetType())) { var vv = m.Invoke(null, new object[] { v }); Console.WriteLine(vv); } }
Console.Read(); }
//反射获取扩展方法 static IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly, Type extendedType) { var query = from type in assembly.GetTypes() where type.IsSealed && !type.IsGenericType && !type.IsNested from method in type.GetMethods(BindingFlags.Static BindingFlags.Public BindingFlags.NonPublic) where method.IsDefined(typeof(ExtensionAttribute), false) where method.GetParameters()[0].ParameterType == extendedType select method; return query; }
} }
我在一开始没用上述反射获取扩展方法时,直接用的 xxx.GetType ().GetMethod (“GetStringValue”) 是获取不到这个扩展方法的, 至于为啥普通方式获取不到扩展方法,这个要看 IL 层的设计了,事实上一个类的扩展方法并不属于该类,而是属于定义他的静态类,之所以能够调用,是因为编译器做了手脚的缘故,编译器遇到这种状况就会调用静态类的方法,通过其 IL 就可以看到真实的调用情况。