C#中的反射与内省:如何窥探代码内部

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:反射的魔力

想象一下,你正在编写一段能够“审视”自身的代码。不是像哈哈镜那样,而是像X光机一样——能够看到结构、属性、方法,甚至在编译时不知道类名的情况下就能调用它们。这不是魔法,这是C#中的反射及其“小妹妹”——C#内省。



为什么需要它?想象一下,你在编写一个插件系统、JSON反序列化器或动态方法调用。没有反射,你不得不编写大量的if-else语句。而有了它,只需几行代码。听起来很吸引人?让我们开始探索吧。



在本文中,我们不仅会讲解理论。我们将编写可以在项目中直接使用的真实代码示例。你将学习如何获取任何类型的信息、凭空创建对象、调用私有方法,甚至读取特性。所有这一切,都使用以其严谨和强大而闻名的C#语言。



什么是C#中的反射与内省?概念区别

这两个术语经常被当作同义词使用,但它们之间有一条细微的界限:

  • C#内省——是程序观察自身结构的能力。你可以了解一个类有哪些字段、包含哪些方法、附加了哪些特性。但你不会改变任何东西。
  • C#反射——是一个更广泛的概念。它包括内省,再加上与代码交互的能力:调用方法、创建对象、修改字段值。

简单来说:内省是“查看”,反射是“查看并操作”。在C#中,这两个功能都由命名空间System.Reflection负责。这是你的主要工具。



实践示例:获取类型信息(Type)

一切从Type类开始。这是反射的基础。可以通过三种方式获取它:

// 方式1:通过 typeof()Type typeFromKeyword = typeof(string);

// 方式2:通过实例 .GetType()string example = "你好,世界!";Type typeFromInstance = example.GetType();

// 方式3:通过程序集(Assembly)Type typeFromAssembly = Assembly.GetExecutingAssembly().GetType("System.String");


现在,有了Type对象,我们可以了解关于这个类的一切。让我们编写一个有用的内省方法:



using System;using System.Reflection;

public class Inspector{ public static void ShowTypeInfo(Type type) { Console.WriteLine($"=== 类型信息:{type.Name} ==="); Console.WriteLine($"完整名称:{type.FullName}"); Console.WriteLine($"是类吗?{type.IsClass}"); Console.WriteLine($"是抽象类吗?{type.IsAbstract}"); Console.WriteLine($"基类:{type.BaseType?.Name}"); Console.WriteLine("公共属性:"); foreach (PropertyInfo prop in type.GetProperties()) { Console.WriteLine($" - {prop.PropertyType.Name} {prop.Name}"); } Console.WriteLine("公共方法:"); foreach (MethodInfo method in type.GetMethods()) { Console.WriteLine($" - {method.ReturnType.Name} {method.Name}({string.Join(", ", method.GetParameters().Select(p => $"{p.ParameterType.Name} {p.Name}"))})"); } }}

// 使用示例Inspector.ShowTypeInfo(typeof(List<int>));/* 输出:=== 类型信息:List`1 ===完整名称:System.Collections.Generic.List`1[[System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]是类吗?True是抽象类吗?False基类:Object

公共属性: - Int32 Capacity - Int32 Count

公共方法: - Void Add(Int32 obj) - Void Clear() - Boolean Contains(Int32 item) ... 以及许多其他方法*/


这就是纯粹的内

博客

书籍推荐