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
相关推荐
斯内科4 小时前
C#德州扑克梭哈游戏(2):牌型与点数比较
游戏·c#·梭哈
柒儿吖4 小时前
rudp Reliable UDP 库在 OpenHarmony 的 lycium 适配与 CRC32 测试
c++·c#·openharmony
CreasyChan4 小时前
unity C# 实现屏蔽敏感词
unity·c#·游戏引擎
光泽雨4 小时前
C#中Process类详解
microsoft·c#·交互
柒儿吖5 小时前
三方库 Boost.Regex 在 OpenHarmony 的 lycium完整实践
c++·c#·openharmony
柒儿吖5 小时前
三方库 Emoji Segmenter 在 OpenHarmony 的 lycium 适配与测试
c++·c#·openharmony
hoiii1875 小时前
基于C#实现的高性能实时MP4录屏方案
开发语言·c#
yongui478345 小时前
基于C#实现Modbus RTU通信
开发语言·c#
wula19946 小时前
C# Revit二次开发 地层工程量统计
开发语言·c#