C#反射

· 浏览次数 : 3

小编点评

**C# 反射概述** **概念** * Type 对象表示一个 .NET 类型。 * Type 对象提供用于访问该类型及其成员的方法和属性的方法。 **语法** * GetFields() 获取类型的字段。 * GetProperties() 获取类型的属性。 * GetMethods() 获取类型的方法。 * GetConstructors() 获取类型的构造函数。 * CreateInstance() 创建类型的实例。 **应用场景** * 动态加载类和创建对象。 * 获取类型和对象的信息。 * 调用方法。 * 创建代理对象。 * 反序列化 JSON 和 XML 等数据格式。 * 生成代码。 **应用场景总结** 反射是一种功能强大的技术,可用于许多不同的应用程序。它可以使您的代码更加灵活、可扩展和可维护。 **其他** * 反射也有一些缺点,例如它可能会降低性能并增加安全性风险。 * 在使用反射之前,请务必权衡利弊。

正文

C#反射

概述

C# 反射(Reflection)是一种强大的机制,它允许程序在运行时访问和操作 .NET 程序集中的类型和成员。
获取程序集、模块 和类型成员信息三者关系介绍请查看

语法

反射的核心概念是 Type 对象。Type 对象表示一个 .NET 类型,并提供用于访问该类型及其成员的方法和属性。
以下是一些常用的 Type 对象方法:

  • GetFields():获取类型的字段
  • GetProperties():获取类型的属性
  • GetMethods():获取类型的的方法
  • GetConstructors():获取类型的构造函数
  • CreateInstance():创建类型的实例
      /// <summary>
      /// 获取程序集信息
      /// </summary>
      public static void GetAssemblyInfo() 
      {
          // 获取当前程序集
          Assembly assembly = Assembly.GetExecutingAssembly();
         //获取dll程序集
          Assembly assembly2 = Assembly.LoadFrom("Note.Basic.dll");
          //获取程序集下的类型信息
         var typesInfo= assembly.DefinedTypes;

          //获取程序集下的模块信息
          var modules = assembly.GetLoadedModules();//.GetModules();
          foreach (var module in modules) 
          {
              //获取模块下的类型信息, 不是Com和嵌套类型
             var types= module.GetTypes().Where(p=>p.Namespace.StartsWith("Note")&&
              p.IsCOMObject==false&&!p.IsNested
             );
          }
      }

        /// <summary>
        /// 获取类型信息
        /// </summary>
        public static void GetTypeInfo() 
        {
            // 获取 Person 类型的 Type 对象
            Type personType = Type.GetType("Note.Basic.Person");

            // 获取 Person 类型的名称
            string typeName = personType.FullName;
            Console.WriteLine("Type name: {0}", typeName);

            // 获取 Person 类型的字段
            FieldInfo[] fields = personType.GetFields();
            foreach (FieldInfo field in fields)
            {
                MessageBox.Show(string.Format("Field: {0} ({1})", field.Name, field.FieldType.Name));
            }

            // 获取 Person 类型的属性
            PropertyInfo[] properties = personType.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                MessageBox.Show(string.Format("Property: {0} ({1})", property.Name, property.PropertyType.Name));
            }

            // 获取 Person 类型的构造函数
            ConstructorInfo[] constructors = personType.GetConstructors();
            foreach (ConstructorInfo constructor in constructors)
            {
                ParameterInfo[] parameters = constructor.GetParameters();
                MessageBox.Show(string.Format("Constructor: {0}({1})", constructor.Name, string.Join(", ", parameters.Select(p => p.ParameterType.Name))));
            }

            // 获取 Person 类型的 SayHello 方法
            MethodInfo sayHelloMethod = personType.GetMethod("Print");
            MessageBox.Show(string.Format("Method: {0}({1})", sayHelloMethod.Name, string.Join(", ", sayHelloMethod.GetParameters().Select(p => p.ParameterType.Name))));

            // 创建 Person 类型的实例
            object? personObject = personType.Assembly.CreateInstance("Note.Basic.Person");

            // 将 object 对象转换为 Person 对象
            Person person = (Person)personObject;

            // 设置 Person 对象的属性
            person.Name = "John Doe";
            person.Age = 30;

            // 调用 Person 对象的方法
            sayHelloMethod.Invoke(person, null);
        }

应用场景

  1. 动态加载类和创建对象: 反射可用于在运行时加载类,而无需显式地引用它们。这对于创建插件和扩展等需要在运行时动态加载代码的应用程序非常有用。

  2. 获取类型和对象的信息: 反射可用于获取有关类型和对象的大量信息,包括类型名称、属性、方法、构造函数等。这对于需要根据类型或对象的信息执行操作的应用程序非常有用。

  3. 调用方法: 反射可用于调用对象的任何方法,包括私有方法。这对于需要在无法直接访问方法的情况下调用方法的应用程序非常有用。

  4. 创建代理对象: 反射可用于创建代理对象,代理对象可以拦截和修改对目标对象的调用。这对于实现日志记录、安全性和其他方面的功能非常有用。

  5. 反序列化 JSON 和 XML 等数据格式: 反射可用于反序列化 JSON 和 XML 等数据格式,将数据转换为对象。这对于需要将数据从字符串转换为对象格式的应用程序非常有用。

  6. 生成代码: 反射可用于生成代码,例如代码生成器和序列化工具可以使用反射来根据类型信息生成代码。

总结

反射是一种功能强大的技术,可用于许多不同的应用程序。它可以使您的代码更加灵活、可扩展和可维护。但是,反射也有一些缺点,例如它可能会降低性能并增加安全性风险。因此,在使用反射之前,请务必权衡利弊。

引用

  1. 博文示例代码 https://github.com/chi8708/DotNetNote/blob/master/Note.Basic/10Generic

与C#反射相似的内容:

C#反射

目录C#反射概述语法应用场景总结引用 C#反射 概述 C# 反射(Reflection)是一种强大的机制,它允许程序在运行时访问和操作 .NET 程序集中的类型和成员。 获取程序集、模块 和类型成员信息,三者关系介绍请查看。 语法 反射的核心概念是 Type 对象。Type 对象表示一个 .NET

C#反射实现插件式开发

前言 插件式架构,一种全新的、开放性的、高扩展性的架构体系。插件式架构设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现。扩展功能与框架以一种很松的方式耦合,两者在保持接口不变的情况下,可以独立变化和发布。基于插件设计并不神秘,相反它比起一团泥的设计更简单,更容易理解。

.NET Core反射获取带有自定义特性的类,通过依赖注入根据Attribute元数据信息调用对应的方法

前言 前段时间有朋友问道一个这样的问题,.NET Core中如何通过Attribute的元数据信息来调用标记的对应方法。我第一时间想到的就是通过C#反射获取带有Custom Attribute标记的类,然后通过依赖注入(DI)的方式获取对应服务的方法并通过反射动态执行类的方法,从而实现更灵活的编程方

【c#版本Openfeign】Net8 自带OpenFeign实现远程接口调用

引言 相信巨硬,我们便一直硬。Net版本到现在已经出了7了,8也已经在预览版了,相信在一个半月就会正式发布,其中也有很多拭目以待的新功能了,不仅仅有Apm和Tap的结合,TaskToAscynResult,以及UnsafeAccessor用来获取私有变量,性能比反射,EMIT更高,还有针对Async

聊一聊对一个 C# 商业程序的反反调试

一:背景 1.讲故事 前段时间有位朋友在微信上找到我,说他对一个商业的 C# 程序用 WinDbg 附加不上去,每次附加之后那个 C# 程序就自动退出了,问一下到底是怎么回事?是不是哪里搞错了,有经验的朋友应该知道,其实这是 商业程序 的反调试机制捣鬼的,为了保护程序隐私,一般都不希望他人对自己做逆

都说 C++ 没有 GC,RAII: 那么我算个啥?

学过 Java、C# 或者其他托管语言(managed languages)的同学,回过头来看 C++ 的时候,第一反应就是 C++ 没有自动垃圾回收器(GC),而不能充分利用的资源被称为垃圾。

C/C++ 恨透了 double free or corruption

计算机编程说到底还是程序员的思维体现,人情世故也会反映在代码的逻辑上, 写代码就如学做人一样,从哪里来到哪里去

C#特性

目录C#特性1. 概括2. 语法定义特性类应用特性获取特性3. 应用场景数据验证序列化和反序列化描述性元数据依赖注入单元测试权限控制AOP(面向切面编程)总结引用 C#特性 1. 概括 C#中的特性是一种用于向代码元素添加元数据的机制。它们允许程序员在代码中添加额外的信息,以影响程序的行为、编译过程

C#判断字符串是否是有效的XML格式数据

说明 在try-catch语句块中,创建XmlDocument对象,并使用LoadXml方法加载xml字符串。如果没有异常,则说明xml字符串是有效的,返回true,反之为false。 代码实现 /// /// Xml字符串格式验证 /// ///

4.1 C++ STL 动态链表容器

List和SList都是C++ STL中的容器,都是基于双向链表实现的,可以存储可重复元素的特点。其中,List内部的节点结构包含两个指针一个指向前一个节点,一个指向后一个节点,而SList只有一个指针指向后一个节点,因此相对来说更节省存储空间,但不支持反向遍历,同时也没有List的排序功能。双向链表的数据元素可以通过链表指针串接成逻辑意义上的线性表,不同于采用线性表顺序存储结构的`Vector`