c# 反射用法及效率对比

 更新时间:2021年02月19日 11:52:17   作者:丹枫无迹  
这篇文章主要介绍了c# 反射用法及效率对比,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下

反射实例化类

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# 反射的资料请关注脚本之家其它相关文章!

相关文章

  • 使用C#验证PDF数字签名有效性的方法示例

    使用C#验证PDF数字签名有效性的方法示例

    数字签名作为PDF文档中的重要安全机制,不仅能够验证文件的来源,还能确保文件内容在传输过程中未被篡改,本文将详细介绍如何使用免费.NET控件通过C#验证PDF签名的有效性以及验证PDF文档是否被修改,需要的朋友可以参考下
    2024-07-07
  • WPF实现背景灯光随鼠标闪动效果

    WPF实现背景灯光随鼠标闪动效果

    这篇文章主要为大家详细介绍了WPF实现背景灯光随鼠标闪动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • C# md5 算法实现代码

    C# md5 算法实现代码

    相对C#来说,md5算法就相对简单很多,因为 System.Security.Cryptography; 已经包含了md5算法。所以我们只需创建MD5类对象即可实现md5算法,今天通过本文给大家介绍C# md5 算法实现,感兴趣的朋友一起看看吧
    2022-11-11
  • C# ListView 点击表头对数据进行排序功能的实现代码

    C# ListView 点击表头对数据进行排序功能的实现代码

    这篇文章主要介绍了C# ListView 点击表头对数据进行排序功能的实现代码,需要的朋友可以参考下
    2017-04-04
  • C#调用C++使用C++/CLI的实现

    C#调用C++使用C++/CLI的实现

    在C#开发过程中,我们可能会遇到需要调用Windows API 或是第三方库的场景,本文主要介绍了C#调用C++使用C++/CLI的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • C# 获取程序集版本、文件版本

    C# 获取程序集版本、文件版本

    C# 获取程序集版本、文件版本的实现代码。
    2009-09-09
  • C#中判断一个集合是否是另一个集合的子集的简单方法

    C#中判断一个集合是否是另一个集合的子集的简单方法

    本文介绍利用C#中内置的系统函数判断一个集合是否是一个集合的子集的方法,此方法代码量极少,分享给大家。
    2016-04-04
  • 详解MongoDB for C#基础入门

    详解MongoDB for C#基础入门

    本篇文章主要介绍了MongoDB for C#基础入门,具体介绍了c#中关于对MongoDB的连接,插入,查询等,有需要的可以了解一下。
    2016-12-12
  • C#实现航班查询及预订功能

    C#实现航班查询及预订功能

    这篇文章给大家介绍利用C#完成航班机票信息查询,航班机票预定等功能。代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2018-02-02
  • C#求数组中元素全排列的方法

    C#求数组中元素全排列的方法

    这篇文章主要介绍了C#求数组中元素全排列的方法,较为详细的分析了数组全排列算法的原理与实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08

最新评论