2.1 反射

1.反射简介

2.反射示例


1.反射简介

csharp 复制代码
1).反射式程序运行时可以看自己的结构(比如: 类, 方法, 属性等), 并能操作这些结构; 反射的核心命名空间

System.Reflection, 核心类是Type(所有类型信息的入口)

2).反射的核心使用场景

a.动态创建对象

b.动态调用方法

c.访问私有成员

d.读取自定义特性

2.反射示例

csharp 复制代码
1).准备测试类

先定义一个基础类, 用于后续反射操作
csharp 复制代码
using System;
using System.Reflection;

// 测试类
public class Person
{
    // 公共字段
    public string Name;
    // 私有字段
    private int _age;
    
    // 公共属性
    public int Age 
    { 
        get => _age; 
        set { if (value > 0) _age = value; }
    }

    // 无参构造函数
    public Person()
    {
        Name = "未知";
        _age = 0;
    }

    // 有参构造函数
    public Person(string name, int age)
    {
        Name = name;
        _age = age;
    }

    // 公共方法
    public string SayHello()
    {
        return $"你好,我是{Name},今年{_age}岁!";
    }

    // 私有方法
    private string GetSecret()
    {
        return $"我的秘密:{Name}的年龄是{_age}";
    }
}

csharp 复制代码
2).获取Type对象(反射的入口)

Type是反射的核心, 获取它有3种常用方式

// 方式1:通过typeof关键字(无需实例)
Type type1 = typeof(Person);

// 方式2:通过对象实例的GetType()方法
Person p = new Person();
Type type2 = p.GetType();

// 方式3:通过类型全名(适用于动态加载场景)
Type type3 = Type.GetType("Person"); // 简单场景,复杂场景需指定程序集名称

// 输出类型基础信息
Console.WriteLine($"类型名称:{type1.Name}");
Console.WriteLine($"是否是类:{type1.IsClass}");

csharp 复制代码
3).动态创建对象

// 3.1 创建无参实例
object obj1 = Activator.CreateInstance(type1);
Person p1 = (Person)obj1;
Console.WriteLine($"无参实例:{p1.Name},{p1.Age}"); // 输出:未知,0

// 3.2 创建有参实例(指定构造函数参数)
Type[] paramTypes = new Type[] { typeof(string), typeof(int) };
ConstructorInfo constructor = type1.GetConstructor(paramTypes);
object[] paramValues = new object[] { "张三", 25 };
object obj2 = constructor.Invoke(paramValues);
Person p2 = (Person)obj2;
Console.WriteLine($"有参实例:{p2.Name},{p2.Age}"); // 输出:张三,25

csharp 复制代码
4).访问字段和属性

// 4.1 读取/修改公共字段
FieldInfo nameField = type1.GetField("Name");
Console.WriteLine($"公共字段Name:{nameField.GetValue(p2)}"); // 输出:张三
nameField.SetValue(p2, "李四");
Console.WriteLine($"修改后Name:{nameField.GetValue(p2)}"); // 输出:李四

// 4.2 读取/修改私有字段(需指定BindingFlags)
FieldInfo ageField = type1.GetField("_age", BindingFlags.NonPublic | BindingFlags.Instance);
Console.WriteLine($"私有字段_age:{ageField.GetValue(p2)}"); // 输出:25
ageField.SetValue(p2, 30);

// 4.3 操作属性
PropertyInfo ageProp = type1.GetProperty("Age");
Console.WriteLine($"属性Age:{ageProp.GetValue(p2)}"); // 输出:30
ageProp.SetValue(p2, 35);
Console.WriteLine($"修改后Age:{ageProp.GetValue(p2)}"); // 输出:35

csharp 复制代码
5).动态调用方法

// 5.1 调用公共方法
MethodInfo sayHelloMethod = type1.GetMethod("SayHello");
object result1 = sayHelloMethod.Invoke(p2, null); // 无参数传null
Console.WriteLine(result1); // 输出:你好,我是李四,今年35岁!

// 5.2 调用私有方法(需指定BindingFlags)
MethodInfo secretMethod = type1.GetMethod("GetSecret", BindingFlags.NonPublic | BindingFlags.Instance);
object result2 = secretMethod.Invoke(p2, null);
Console.WriteLine(result2); // 输出:我的秘密:李四的年龄是35
相关推荐
Neil201311 小时前
ajax跨域请求
c#
唐青枫11 小时前
别把 Razor 当成几段 HTML:C#.NET Razor Pages、MVC 视图与实战详解
c#·.net
专注仿真17 小时前
CMO模型文档-活动单元基类
c#·模型·cmo·活动单元基类
我是苏苏20 小时前
Agent 开发实战 :C#实现语义检索!向量数据库Qdrant的下载安装及调试步骤
c#·ai编程
光泽雨20 小时前
IEnumerable<T> 详细讲解
c#·c
Lost of 程序猿21 小时前
.NET 10 船端单机部署与离线升级实战:从闪退事故到无感回滚
c#·asp.net·.net
淡海水1 天前
11-04-Unity-Span-foreach-LINQ的分配与热路径边界
unity·c#·linq·foreach·span
唐青枫1 天前
对象到底住在哪里?C#.NET 托管堆从分配、GC 到内存排查
c#·.net
fogota2 天前
Emoji与Segoe MDL2 Assets的比较
c#·wpf
灸木2 天前
C# 多线程与异步
c#