C#基础——反射
C#基础——反射
C# 反射需要用到System.Reflection
类完成。
准备工作
准备一个需要被拿来反射的类
class MyClass
{
// 字段
private string name;
private int age;
private bool sex;
// 属性
public string Name { get { return name; } set { name = value; } }
public int Age { get { return age; } set { age = value; } }
public bool Sex { get { return sex; } set { sex = value; } }
// 无参构造器
public MyClass(){}
// 有参构造器
public MyClass(string name,int age,bool sex) {
Name = name;
Age = age;
Sex = sex;
}
public void print(string message)
{
Console.WriteLine("myclass:" + message);
}
public void print(string message, bool show)
{
if (show)
Console.WriteLine("myclass:" + message);
}
public int add(int a, int b)
{
return a + b;
}
private int addAll(int[] arrs)
{
int val = 0;
foreach (int item in arrs)
{
val += item;
}
return val;
}
}
获取反射类
用类反射
Type type = typeof(MyClass);//用类反射
用字符串形式的全类名反射
Type type = Assembly.GetExecutingAssembly().GetType("ConsoleApp1.MyClass");
反射构造器
获取全部构造器
Type type = typeof(MyClass);//用类反射
ConstructorInfo[] constructorInfo = type.GetConstructors();
获取指定构造器
Type type = typeof(MyClass);
//其中的参数是指定构造器的参数类型数组
ConstructorInfo constructorInfo = type.GetConstructor(new Type[] { typeof(string),typeof(int),typeof(bool)});
反射字段
获取全部字段
方法GetFields
不添加任何参数:获取public
修饰的所有字段
Type type = typeof(MyClass);
// 获取类字段
FieldInfo[] fields = type.GetFields();
foreach (FieldInfo field in fields)
{
Console.WriteLine($"字段名:{field.Name} 类型:{field.FieldType.FullName}");
}
获取指定字段
获取public
修饰的字段,但为了保持代码的封装性,字段一般是不用public
修饰字段。所以在获取字段的时候还需要加上要求——BindingFlags
Type type = typeof(MyClass);
// 第一个参数是字段名,第二个参数是“要求”
FieldInfo field = type.GetField("name", BindingFlags.NonPublic | BindingFlags.Instance);
BindingFlags 是 C# 反射 API 中一个非常重要的枚举,它用于指定在反射操作中如何绑定到类型成员(如字段、属性、方法、构造函数等)。
这个枚举提供了一系列标志(flags),这些标志以按位或(bitwise OR)的方式组合起来,以指定反射操作的详细行为和范围。以下是一些常用的 BindingFlags 标志及其描述:
Default:默认绑定标志,通常不直接使用,而是与其他标志组合使用。
IgnoreCase:在搜索类型成员时忽略大小写。
DeclaredOnly:仅搜索在当前类型上直接声明的成员,不搜索继承的成员。
Instance:指定搜索实例成员(非静态成员)。
Static:指定搜索静态成员。
Public:指定搜索公共成员。
NonPublic:指定搜索非公共成员(如 private、protected、internal 等)。
FlattenHierarchy:在搜索时,将层次结构中的成员视为在同一级别上。
InvokeMethod:用于调用方法。
GetField:用于获取字段的值。
SetField:用于设置字段的值。
GetProperty:用于获取属性的值。
SetProperty:用于设置属性的值。
CreateInstance:用于创建类的实例。
通过按位或操作符(|)组合这些标志,以满足特定的反射需求。例如,如果你想要搜索一个类的所有公共和非公共的静态字段,你可以使用
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic
反射方法
获取public
修饰的方法
using System.Reflection
Type type = typeof(MyClass);
MethodInfo[] methodInfo = type.GetMethods();//仅获取内部public修饰的方法
获取指定的private修饰的方法
MethodInfo field = type.GetMethod("addAll", BindingFlags.NonPublic | BindingFlags.Instance,null,new Type[] { typeof(int[])},null);
获取指定的public修饰的方法
MethodInfo field = type.GetMethod("add");
获取方法参数信息
MethodInfo[] methodInfo = type.GetMethods();
foreach (MethodInfo item in methodInfo)
{
// 获取方法名
Console.WriteLine("方法名:" + item.Name);
// 获取方法参数
ParameterInfo[] parameterInfo = item.GetParameters();
foreach (ParameterInfo param in parameterInfo)
{
// 获取方法参数类型
Type paramType = param.ParameterType;
// 获取参数名
string paramName = param.Name;
Console.WriteLine($"\t参数名:{paramName}\t类型:{paramType.FullName}");
}
}
获取方法返回值信息
// 获取方法的返回值类型
Type backType = item.ReturnType;
Console.WriteLine($"\t返回值:{backType.Name}\t返回类型:{backType.FullName}\n");
反射属性
获取public修饰的全部属性
Type type = typeof(MyClass);
PropertyInfo[] attributes = type.GetProperties();
foreach (PropertyInfo item in attributes)
{
Console.WriteLine($"全类名:{item.PropertyType.FullName} 属性名:{item.Name}");
}
获取指定属性(属性一般使用public
修饰,可直接获取)
Type type = typeof(MyClass);
PropertyInfo field = type.GetProperty("Name");
利用反射实例化对象
Type type = typeof(MyClass);
ConstructorInfo constructorInfo = type.GetConstructor(new Type[] { typeof(string),typeof(int),typeof(bool)});
object obj = constructorInfo.Invoke(new object[] {"jack",18,true});
利用反射调用方法
Type type = typeof(MyClass);
// 获取构造器
ConstructorInfo constructorInfo = type.GetConstructor(new Type[] { typeof(string),typeof(int),typeof(bool)});
// 实例化类对象
object obj = constructorInfo.Invoke(new object[] {"jack",18,true});
// 获取方法
MethodInfo method = type.GetMethod("addAll", BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(int[]) }, null);
//第一个参数是实例化对象,第二个参数是方法传参
int res = (int)method.Invoke(obj, new object[] { new int[] { 1, 2, 3, 4 } });
本文来自博客园,作者:勤匠,转载请注明原文链接:https://www.cnblogs.com/JarryShu/articles/18189702
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现