• C#之反射


            反射是指对一个程序集中的元数据进行检查的过程。说明白一点,就是可以访问和使用一个dll里面所有的东西,并且是运行动态时的调用,而不是普通编译时的绑定,这样使程序更加的自由和灵活,但是性能较低。

    反射一般可以用于:插件的开发、特性和程序的动态调用等等。

    1.建立2个项目,第一个输出类库,第二个输出控制台程序,然后使用反射的方式调用

    2.第一个类库的dll是

    代码

    1. using System;
    2. namespace ClassLibrary1
    3. {
    4. public class Class1
    5. {
    6. public Class1()
    7. {
    8. Console.WriteLine("无参构造");
    9. }
    10. public Class1(string a)
    11. {
    12. Console.WriteLine("有参构造");
    13. }
    14. public string A(int a, int b)
    15. {
    16. return "有参数有返回值:" + a + b;
    17. }
    18. public void B(int a, int b)
    19. {
    20. Console.WriteLine("有参数无返回值:" + a + b);
    21. }
    22. public void C()
    23. {
    24. Console.WriteLine("无参无返回值");
    25. }
    26. }
    27. }

    3. 第二个项目使用反射调用

    这里我们用了4种方法,分别是:

    a.调用构造参数

    b.调用有参数有返回值

    c.调用有参数无返回值

    d.调用无参无返回值

    1. using Newtonsoft.Json;
    2. using System;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5. using System.Reflection;
    6. namespace ConsoleApp4
    7. {
    8. static class Program
    9. {
    10. static void Main(string[] args)
    11. {
    12. Assembly assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + @"a\ClassLibrary1.dll"); //获取整个dll文件
    13. Type type = assembly.GetType("ClassLibrary1.Class1"); //获取dll中的类型,参数是命名空间.类名
    14. ConstructorInfo info2 = type.GetConstructor(new Type[] { typeof(string) });
    15. info2.Invoke(new object[] { "asd" }); //执行有参构造函数
    16. Console.WriteLine("####################");
    17. Type type1 = assembly.GetType("ClassLibrary1.Class1"); //获取dll中的类型,参数是命名空间.类名
    18. MethodInfo mi1 = type1.GetMethod("A"); //调用方法A
    19. Object obj1 = Activator.CreateInstance(type1); //快速实例化,相当于new
    20. object[] objParams1 = new object[] { 1, 2 }; //方法的参数
    21. Object returnValue = mi1.Invoke(obj1, objParams1); //接收参数
    22. Console.WriteLine(returnValue);
    23. Console.WriteLine("####################");
    24. Type type2 = assembly.GetType("ClassLibrary1.Class1"); //获取dll中的类型,参数是命名空间.类名
    25. MethodInfo mi2 = type2.GetMethod("B"); //调用方法B
    26. Object obj2 = Activator.CreateInstance(type2); //快速实例化,相当于new
    27. object[] objParams2 = new object[] { 1, 2 }; //方法的参数
    28. mi2.Invoke(obj2, objParams2); //执行
    29. Console.WriteLine("####################");
    30. Type type3 = assembly.GetType("ClassLibrary1.Class1"); //获取dll中的类型,参数是命名空间.类名
    31. MethodInfo mi3 = type3.GetMethod("C"); //调用方法C
    32. Object obj3 = Activator.CreateInstance(type3); //快速实例化,相当于new
    33. mi3.Invoke(obj3, null); //执行
    34. Console.ReadKey();
    35. }
    36. }
    37. }

    4.效果

    拓展

    其实上面的方法也可以是InvokeMember方法完成。

    1.代码

    1. using Newtonsoft.Json;
    2. using System;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5. using System.Reflection;
    6. namespace ConsoleApp4
    7. {
    8. static class Program
    9. {
    10. static void Main(string[] args)
    11. {
    12. Assembly assembly = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + @"a\ClassLibrary1.dll"); //获取整个dll文件
    13. //Type type = assembly.GetType("ClassLibrary1.Class1"); //获取dll中的类型,参数是命名空间.类名
    14. //ConstructorInfo info2 = type.GetConstructor(new Type[] { typeof(string) });
    15. //info2.Invoke(new object[] { "asd" }); //执行有参构造函数
    16. //Console.WriteLine("####################");
    17. //Type type1 = assembly.GetType("ClassLibrary1.Class1"); //获取dll中的类型,参数是命名空间.类名
    18. //MethodInfo mi1 = type1.GetMethod("A"); //调用方法A
    19. //Object obj1 = Activator.CreateInstance(type1); //快速实例化,相当于new
    20. //object[] objParams1 = new object[] { 1, 2 }; //方法的参数
    21. //Object returnValue = mi1.Invoke(obj1, objParams1); //接收参数
    22. //Console.WriteLine(returnValue);
    23. //Console.WriteLine("####################");
    24. //Type type2 = assembly.GetType("ClassLibrary1.Class1"); //获取dll中的类型,参数是命名空间.类名
    25. //MethodInfo mi2 = type2.GetMethod("B"); //调用方法B
    26. //Object obj2 = Activator.CreateInstance(type2); //快速实例化,相当于new
    27. //object[] objParams2 = new object[] { 1, 2 }; //方法的参数
    28. //mi2.Invoke(obj2, objParams2); //执行
    29. //Console.WriteLine("####################");
    30. //Type type3 = assembly.GetType("ClassLibrary1.Class1"); //获取dll中的类型,参数是命名空间.类名
    31. //MethodInfo mi3 = type3.GetMethod("C"); //调用方法C
    32. //Object obj3 = Activator.CreateInstance(type3); //快速实例化,相当于new
    33. //mi3.Invoke(obj3, null); //执行
    34. Type type4 = assembly.GetType("ClassLibrary1.Class1"); //获取dll中的类型,参数是命名空间.类名
    35. object obj4 = Activator.CreateInstance(type4);
    36. //BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static 静态的时候需要加
    37. Object returnValue4 = type4.InvokeMember("A", BindingFlags.InvokeMethod, null, obj4, new object[] { 1, 2 });
    38. Console.WriteLine(returnValue4);
    39. type4.InvokeMember("B", BindingFlags.InvokeMethod,null, obj4, new object[] { 1, 2 });
    40. type4.InvokeMember("C", BindingFlags.InvokeMethod ,null, obj4, null);
    41. Console.ReadKey();
    42. }
    43. }
    44. }

    2.效果是一样的

    其中Assembly.LoadFile和Assembly.LoadFrom是有区别的。

    Assembly.LoadFile,只加载自己,不加载依赖项,意思就是除过自己,不加载关联的dll。

    Assembly.LoadFrom,不仅加载自己,还加载依赖项,除过自己,还加载自己关联其他的dll。

    大部分的内容都在type点里面,里面包含了所有的对象,比如字段,属性,方法等等

    来源:C#之反射_c#可以反射么_故里2130的博客-CSDN博客

  • 相关阅读:
    优先级队列(堆)——小记
    【python基础】生成式、装饰器、高阶函数
    小米软件开发二面和中兴软开一面
    win10下用cmake编译zlib并验证
    设计模式之代理模式
    强化服务器安全!CentOS 7如何使用fail2ban防范SSH暴力破解攻击?
    python自学入门(打卡十二)2022-12-04
    大阳能充电新技术---Powerfoyle
    [pyqt5]No module named ‘PyQt5.QtMultimedia
    HTML5基础:label,select,textarea
  • 原文地址:https://blog.csdn.net/u012563853/article/details/126947418