反射实例化类
public class Person{ public string Name { get; set; } public Person(string name) { this.Name = name; } public string Say(string msg) { return $"{Name}: {msg}"; }}class Program{ // 测试次数 const int count = 10000000; static void Main(string[] args) { CreateInstance0(); CreateInstance1(); CreateInstance2(); CreateInstance3(); CreateInstance4(); Console.Read(); } static void CreateInstance0() { Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { Person person = new Person("张三"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - new"); } static void CreateInstance1() { Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { object person = Activator.CreateInstance(typeof(Person), "张三"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - Activator.CreateInstance"); } static void CreateInstance2() { Assembly assembly = Assembly.GetExecutingAssembly(); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { Person obj = (Person)assembly.CreateInstance("ConsoleTest.Person", true, BindingFlags.Default, null, new object[] { "张三" }, null, null); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - Assembly.CreateInstance"); } static void CreateInstance3() { Assembly assembly = Assembly.GetExecutingAssembly(); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { Type type = assembly.GetType("ConsoleTest.Person"); object person = Activator.CreateInstance(type, "张三"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - Assembly.CreateInstance1"); } static void CreateInstance4() { Assembly assembly = Assembly.GetExecutingAssembly(); Stopwatch watch = new Stopwatch(); watch.Start(); Type type = assembly.GetType("ConsoleTest.Person"); for (var i = 0; i < count; i++) { object person = Activator.CreateInstance(type, "张三"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - Assembly.CreateInstance2"); }}
- 通过反射实例化对象,要比直接 new 要慢 50 倍左右
- assembly.CreateInstance 要比 Activator.CreateInstance 慢,主要的性能损耗在 Assembly.GetType
反射调用类的方法
class Program{ // 测试次数 const int count = 10000000; static void Main(string[] args) { InvokeMethod0(); InvokeMethod1(); InvokeMethod2(); InvokeMethod3(); InvokeMethod4(); Console.Read(); } static void InvokeMethod0() { Person person = new Person("张三"); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string name = person.Say("Hello World!"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 直接调用"); } static void InvokeMethod1() { Person person = (Person)Activator.CreateInstance(typeof(Person), "张三"); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string name = person.Say("Hello World!"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 反射缓存类调用"); } static void InvokeMethod2() { Person person = (Person)Activator.CreateInstance(typeof(Person), "张三"); MethodInfo method = typeof(Person).GetMethod(nameof(Person.Say), new Type[] { typeof(string) }); Func<string, string> func = (Func<string, string>)method.CreateDelegate(typeof(Func<string, string>), person); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string result = func("Hello World!"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 使用反射创建出来的委托调用"); } static void InvokeMethod3() { Person person = (Person)Activator.CreateInstance(typeof(Person), "张三"); MethodInfo method = typeof(Person).GetMethod(nameof(Person.Say), new Type[] { typeof(string) }); object[] parameters = new object[] { "Hello World!" }; Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string name = (string)method.Invoke(person, parameters); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 使用反射得到的方法缓存调用"); } static void InvokeMethod4() { Person person = (Person)Activator.CreateInstance(typeof(Person), "张三"); object[] parameters = new object[] { "Hello World!" }; Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string result = (string)(typeof(Person).GetMethod(nameof(Person.Say))?.Invoke(person, parameters)); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 直接使用反射调用"); }}
- 反射得到实例后调用方法和直接调用方法效率一样
- 缓存反射方法调用和直接使用反射调用都非常耗效率
以上就是c# 反射用法及效率对比的详细内容,更多关于c# 反射的资料请关注其它相关文章!