首页 > 编程语言 >Net6 反射反射程序员的快乐/遍历属性、字段、构造方法、函数及相关操作

Net6 反射反射程序员的快乐/遍历属性、字段、构造方法、函数及相关操作

时间:2022-11-21 16:00:46浏览次数:55  
标签:反射 Console string 构造方法 stu BindingFlags WriteLine var Net6

十年河东,十年河西,莫欺少年穷

学无止境,精益求精

反射反射,程序员的快乐,利用反射可以获取到私有属性及其值 

在C#中反射无处不在,用好反射,就可以为所欲为

有这么一个学生类:

public class student
{
/// <summary>
/// 年龄
/// </summary>
public int stuAge;
/// <summary>
/// 是否是管理者
/// </summary>
private bool isManager;
/// <summary>
/// 学号
/// </summary>
private string stuNo { get; set; }
/// <summary>
/// 性名
/// </summary>
public string stuName { get; set; }
/// <summary>
/// 性别
/// </summary>
public string stuSex { get; set; }
/// <summary>
/// 班级
/// </summary>
private string grand { get; set; }

public student()
{

}
public student(string stuNo,string grand)
{
this.stuNo = stuNo;
this.grand = grand;
}

public string Getsss()
{
return "ssss";
}
public string Getsss(string sss)
{
return sss;
}


}

View Code

学号、班级为私有属性。姓名、性别公有属性。年龄,是否是管理者为成员变量。并拥有无参和有参两种构造函数和两个自定义方法,那么,如何利用反射对它进行操作呢,且听我慢慢道来

1、遍历属性

1.1、遍历私有属性

static void Main(string[] args)
{
var stu = new student("001","魔教");
stu.stuName = "东方不败";
stu.stuSex = "人妖";
var typ2 = stu.GetType();
///
Console.WriteLine("---------------------获取私有属性------------------------");
foreach (var item in typ2.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic))
{
Console.WriteLine(item.Name + ":" + item.PropertyType + ":" + item.CanRead);
}
}

1.2、遍历公有有属性

Console.WriteLine("---------------------获取公有属性------------------------");
foreach (var item in typ2.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
Console.WriteLine(item.Name + ":" + item.PropertyType + ":" + item.CanRead);
}

1.3、遍历所有属性

Console.WriteLine("---------------------获取所有属性------------------------");
foreach (var item in typ2.GetProperties(BindingFlags.Instance | BindingFlags.Public|BindingFlags.NonPublic))
{
Console.WriteLine(item.Name + ":" + item.PropertyType + ":" + item.CanRead);
}

Net6 反射反射程序员的快乐/遍历属性、字段、构造方法、函数及相关操作_无参构造函数

 

 1.4、获取某个属性

var p_1 = typ2.GetProperty("stuSex");
Console.WriteLine(p_1?.Name);

2、遍历字段

遍历字段和遍历属性类似,不同的是,遍历字段可以将类中的成员变量和属性一块遍历出来

2.1、遍历私有字段

static void Main(string[] args)
{
var stu = new student("001","魔教");
stu.stuName = "东方不败";
stu.stuSex = "人妖";
var typ2 = stu.GetType();
Console.WriteLine("---------------------获取私有字段------------------------");
//
var flds = typ2.GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
foreach (var item in flds)
{
Console.WriteLine(item.Name + ":" + item.FieldType + ":" + item.IsStatic);
}
}

Net6 反射反射程序员的快乐/遍历属性、字段、构造方法、函数及相关操作_字段_02

 

 遍历私有字段时,会遍历所有私有属性及成员变量,但stuName 和 stuSex 两个公有的属性为什么也被遍历出来了?

问题出在get;set;构造器,在原始的C#中,构造器是这样的

private int money;//私有字段

public int Money //属性
{
//GET访问器,可以理解成另类的方法,返回已经被赋了值的私有变量money
get { return money; }
//SET访问器,将我们打入的值赋给私有变量money
set { money = value; }
}

现在的get;set;构造器只是一种简写,因此在C#底层,依旧会采用上述构造。这样公有的属性被遍历私有字段时带出来就不足为奇了!

2.2、遍历公有字段

Console.WriteLine("---------------------获取公有字段------------------------");
//
var flds = typ2.GetFields(BindingFlags.Instance | BindingFlags.Public);
foreach (var item in flds)
{
Console.WriteLine(item.Name + ":" + item.FieldType + ":" + item.IsStatic);
}

Net6 反射反射程序员的快乐/遍历属性、字段、构造方法、函数及相关操作_字段_03

2.3、遍历所有字段

Console.WriteLine("---------------------获取所有字段------------------------");
//
var flds = typ2.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var item in flds)
{
Console.WriteLine(item.Name + ":" + item.FieldType + ":" + item.IsStatic);
}

2.4、获取某个字段

var stu = new student("001","魔教");
stu.stuName = "东方不败";
stu.stuSex = "人妖";
var typ2 = stu.GetType();
Console.WriteLine("---------------------获取某个字段------------------------");
//
var fld = typ2.GetField("stuAge");
Console.WriteLine(fld?.Name);

3、获取其他常用信息

static void Main(string[] args)
{
var stu = new student("001","魔教");
stu.stuName = "东方不败";
stu.stuSex = "人妖";
var typ2 = stu.GetType();
Console.WriteLine("--------------------获取其他信息-------------------------");
Console.WriteLine("他的全称:" + typ2.FullName);
Console.WriteLine("他的命名空间:" + typ2.Namespace);
Console.WriteLine("他的名称:" + typ2.Name);
Console.WriteLine("他的基类:" + typ2.BaseType);
}

Net6 反射反射程序员的快乐/遍历属性、字段、构造方法、函数及相关操作_创建对象_04

 4、通过反射创建对象

4.1、利用无参构造函数创建对象

Activator.CreateInstance(obj)

执行无参构造函数

static void Main(string[] args)
{
Console.WriteLine("--------------------通过反射创建对象-------------------------");
var stu_RF = typeof(student);
///执行无参构造函数
var stu = Activator.CreateInstance(stu_RF) as student;

stu.stuName = "东方不败";
stu.stuSex = "人妖";
stu.stuAge = 18;
Console.WriteLine($"姓名:{stu.stuName},性别:{stu.stuSex},年龄:{stu.stuAge}");
}

这里创建的对象相当于

student s = new student() { stuAge = 18, stuName = "东方不败", stuSex = "人妖" };

4.2、利用有参构造函数创建对象

Activator.CreateInstance(obj,params object[] args)

执行有参构造函数,args 为参数

static void Main(string[] args)
{
Console.WriteLine("--------------------通过反射创建对象-------------------------");
var stu_RF = typeof(student);
///执行有参构造函数
var stu = Activator.CreateInstance(stu_RF,"001","魔教") as student;
stu.stuName = "东方不败";
stu.stuSex = "人妖";
stu.stuAge = 18;
Console.WriteLine($"姓名:{stu.stuName},性别:{stu.stuSex},年龄:{stu.stuAge}");
}

这里创建的对象相当于

student s = new student("001","魔教") { stuAge = 18, stuName = "东方不败", stuSex = "人妖" };

4.3、利用泛型方法创建对象

Activator.CreateInstance<T>

利用泛型构造对象时,只能执行无参构造函数

static void Main(string[] args)
{
Console.WriteLine("--------------------通过反射创建对象-------------------------");
var stu_RF = typeof(student);
///执行无参构造函数
var stu = Activator.CreateInstance<student>();
stu.stuName = "东方不败";
stu.stuSex = "人妖";
stu.stuAge = 18;
Console.WriteLine($"姓名:{stu.stuName},性别:{stu.stuSex},年龄:{stu.stuAge}");
}

5、设置或读取反射创建的对象的属性/字段

通过反射创建对象后,我们可以通过setValue 和 getValue 来设置/读取相关属性/字段的值

static void Main(string[] args)
{
var stu_RF = typeof(student);
///执行有参构造函数
var stu = Activator.CreateInstance(stu_RF, "001", "魔教") as student;
var typ2 = stu.GetType();
var p_1 = typ2.GetProperty("stuName");
p_1.SetValue(stu, "东方不败");
var p_2 = typ2.GetProperty("stuSex");
p_2.SetValue(stu, "人妖");
//获取私有属性 需要声明 BindingFlags.Instance|BindingFlags.NonPublic
var p_3 = typ2.GetProperty("grand",BindingFlags.Instance|BindingFlags.NonPublic);
p_3.SetValue(stu, "魔教");
//获取公有字段 用GetField 需要声明 BindingFlags.Instance|BindingFlags.Public
var p_4 = typ2.GetField("stuAge", BindingFlags.Instance | BindingFlags.Public);
p_4.SetValue(stu, 18);
//获取私有字段 用GetField 需要声明 BindingFlags.Instance|BindingFlags.NonPublic
var p_5 = typ2.GetField("isManager", BindingFlags.Instance | BindingFlags.NonPublic);
p_5.SetValue(stu, true);
// bool 值需要特殊处理下
var zhiweibol = (bool)p_5?.GetValue(stu);
string zhiwei = string.Empty;
if (zhiweibol)
{
zhiwei = "教主";
}
Console.WriteLine($"姓名为:{p_1?.GetValue(stu)},性别为:{p_2?.GetValue(stu)},所属教派为:{p_3?.GetValue(stu)},年龄为:{p_4?.GetValue(stu)},职位为:{zhiwei}");
Console.ReadKey();
}

Net6 反射反射程序员的快乐/遍历属性、字段、构造方法、函数及相关操作_创建对象_05

 6、通过反射,加载程序集

6.1、通过dll文件路径加载程序集

新建一个类库项目,命名为:swapModels,控制台程序引用该项目

static void Main(string[] args)
{
//读取当前Program类所在路径
var rootPath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
var rootDir = new DirectoryInfo(rootPath);
var basePath = rootDir.FullName;
var dllName = "swapModels.dll";
string assemblyPath = Path.Combine(basePath, dllName);
//通过路径加载程序集
var assembly = Assembly.LoadFrom(assemblyPath);

Console.ReadKey();
}

6.2、通过命名空间加载程序集

新建一个类库项目,命名为:swapModels,控制台程序引用该项目

static void Main(string[] args)
{
var assembly = Assembly.LoadFrom("swapModels");
Console.ReadKey();
}

以上两种方法都可以加载引用项目所在的程序集。

7、通过反射操作构造方法

7.1、无参构造方法

static void Main(string[] args)
{
var typ = typeof(student);
//获取无参构造函数
var Constructor = typ.GetConstructor(new Type[] { });
//无参构造函数创建的对象
var obj = Constructor.Invoke(null) as student;
//
var obj2 = Activator.CreateInstance(typ) as student;
if (obj.Equals(obj2))
{
Console.WriteLine("两个无参对象一致");
}
else
{
Console.WriteLine("两个无参对象不一致");
}
}

7.2、有参构造方法

static void Main(string[] args)
{
var typ = typeof(student);
//获取有参构造函数--注明构造方法的参数类型
var ConstructorYc = typ.GetConstructor(new Type[] { typeof(string),typeof(string)});
//传入参数
var obj3 = ConstructorYc.Invoke(new object[] { "001", "魔教" } ) as student;
obj3.stuName = "东方不败";
Console.ReadKey();
}

Net6 反射反射程序员的快乐/遍历属性、字段、构造方法、函数及相关操作_创建对象_06

 

 8、通过反射,操作方法【其他普通方法】

8.1、获取所有方法

static void Main(string[] args)
{
var typ = typeof(student);
//获取有参构造函数--注明构造方法的参数类型
var lst = typ.GetMethods( BindingFlags.Instance|BindingFlags.Public| BindingFlags.NonPublic);
foreach(var item in lst)
{
Console.WriteLine(item.Name + ":" + item.ReturnType);
}
Console.ReadKey();
}

Net6 反射反射程序员的快乐/遍历属性、字段、构造方法、函数及相关操作_无参构造函数_07

 

 8.2、调用方法

Getsss 有两个方法重载,因此,在调用自定义方法时,需要指定有无参数,如果有参数,需要指定参数类型及传入响应参数

static void Main(string[] args)
{
var typ = typeof(student);
//调用无参方法
var Mth = typ.GetMethod("Getsss",new Type[] { });
var ConstructorYc = typ.GetConstructor(new Type[] { typeof(string), typeof(string) });
//传入参数
var obj = ConstructorYc.Invoke(new object[] { "001", "魔教" }) as student;
var result_1 = Mth.Invoke(obj ,null);
Console.WriteLine(result_1);
//调用有参数的方法 指定参数类型
var Mth2 = typ.GetMethod("Getsss", new Type[] {typeof(string) });
//传入参数
var result_2 = Mth2.Invoke(obj,new object[] { "哈哈哈哈"});
Console.WriteLine(result_2);

Console.ReadKey();
}

@天才卧龙的博客

 



标签:反射,Console,string,构造方法,stu,BindingFlags,WriteLine,var,Net6
From: https://blog.51cto.com/u_15316082/5874090

相关文章

  • Java使用反射生成JDK动态代理
    Java使用反射生成JDK动态代理1.*使用反射生成JDK动态代理在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口可以生成JD......
  • Java通过反射生成并操作对象
    Java通过反射生成并操作对象1.*使用反射生成并操作对象Class对象可以获得该类里的方法(由Method对象表示)、构造器(由Constructor对象表示)、Field(由Field对象表示),这3个类都......
  • Java通过反射查看类信息
    Java通过反射查看类信息1.*通过反射查看类信息Java程序中的许多对象在运行时都会出现两种类型:编译时类型和运行时类型,例如代码:“Personp=newStudent()”,这行代码将......
  • Docker发布.net6.0项目
     1、创建一个项目,并且添加docker支持(我这边是用了一个以前就创建好的项目)如下图,添加docker支持,选择linux,添加后会自动生成一个Dockerfile文件(这个文件是构建docker镜......
  • C#ORM(反射+泛型)参考范例
    使用控制台:1.数据库字符串<?xmlversion="1.0"encoding="utf-8"?><configuration><startup><supportedRuntimeversion="v4.0"sku=".NETFramework,V......
  • C++ 反射实现
    //class.h#ifndefCLASS_H#defineCLASS_H#include<iostream>#include<functional>#include<memory>#include<map>#include<stdarg.h>usingnamespacestd;......
  • 架构之反射实现源代码(不知道要干什么确需要知道能干什么)
    做过架构的朋友或许都有过不知道开发人员要干什么确需要知道开发人员能干什么的困惑,估计大家的解决思路应该也会往一处想-反射介绍下自己的实现思路和代码:1、定义接口如:  ......
  • java构造方法的作用
    构造方法作用就是对类进行初始化。如果你没有定议任何构造方法的形式,程式会为你取一个不带任何参数的构造函数,那么你产生类的对像时只能用不带参数的方法,如:classa{}//没......
  • Java反射与安全问题
    1.Java反射机制Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及......
  • Net6 操作时序数据库 Influxdb ,插入数据
    十年河东,十年河西,莫欺少年穷学无止境,精益求精1、引入组件  2、书写代码publicclassInfluxDto{privatereadonlyILogger<InfluxDto>logger;......