**
程序集与元数据
**
什么是程序集?程序及是编译器编译得到的,供进一步编译执行的中间产物
在windo系统中,一般表现后缀位.dll(库文件)或者是.exe(可执行程序)
.dll文件是类库工程文件,是纯代码逻辑,不能直接运行
元数据
元数据就是用来描述数据的数据,保存在程序集中。例如,程序中的类,类中的函数、变量等等。
**
反射的概念
程序在运行时,可以查看其他程序集或者自身的元数据,这个过程叫做反射。
通过反射,可以得到程序集中的各种信息。
**
反射的语法
Type类
Type 类的信息 类
反射的基础
访问元数据的主要方式
首先创建一个类用于测试
class Test
{
private int id;
private string name;
public int a = 12;
public Test()
{
}
public Test(int id)
{
this.id = id;
}
public Test(int id,string name):this(id)//调用上面的重载
{
this.name = name;
}
public void Xinxi()
{
Console.WriteLine(id + " " + name);
}
}
- 获取Type
//1.object中的GetType()可以获取对象的Type
int a = 1;
Type type1 = a.GetType();//把a 属于的 类中的信息 传递给type1
//2.通过typeof关键字 传入类名 得到Type对象(一般用于同一个程序集)
Type type2 = typeof(Test);
//3.通过类名获取
//注意 类名必须包含命名空间,不然找不到
//Type type3 = Type.GetType("Int32");没有包含命名空间,找不到
Type type3 = Type.GetType("System.Int32");
- 得到类的程序集信息
//可以通过Type得到类型所在的程序集信息
Console.WriteLine(type1.Assembly);
- 获取类中的所有 公共 成员
//需要引入命名空间using System.Reflection
//MemberInfo 信息类 可以存储所有信息
MemberInfo[] infos = type2.GetMembers();
foreach(var item in infos)
{
Console.WriteLine(item);
}
- 获取类的所有构造函数并且调用
//ConstructorInfo类 可以储存构造函数的信息
ConstructorInfo[] ctorInfo = type2.GetConstructors();
foreach(var item in ctorInfo)
{
Console.WriteLine(item);
}
- 获取其中一个构造函数 并执行
//得到构造函数传入Type类型的数组,数组中内容按顺序是参数类型
//1.获取无参构造
ConstructorInfo info = type2.GetConstructor(new Type[0]);
Test obj = info.Invoke(null) as Test;
//2.获取有参构造
ConstructorInfo info2 = type2.GetConstructor(new Type[] { typeof(int) });
Test obj2 = info2.Invoke(new object[] { 2 }) as Test;
- 获取类的公共成员变量
//1.得到所有成员变量
FieldInfo[] fiInfos = type2.GetFields();
foreach(var item in fiInfos)
{
Console.WriteLine(item);
}
//2.得到指定名称的公共成员变量
FieldInfo fiInfo1 = type2.GetField("a");
Console.WriteLine(fiInfo1);
//3.通过反射获取和设置对象的值
Test test1 = new Test();
test1.a = 5;
//获取对象某个变量的值
Console.WriteLine(fiInfo1.GetValue(test1));
//设置指定对象的某个变量
fiInfo1.SetValue(test1, 5);
- 获得类的公共成员方法
//通过Type类中的GetMethod方法 得到类中的方法
//如果方法存在重载,GetMethod(string name,new Type[] {typeof(type)})
MethodInfo[] meInfos = type2.GetMethods();
MethodInfo meInfo1 = type2.GetMethod("Xinxi");
//调用该方法
Test test2 = new Test(1, "sss");
meInfo1.Invoke(test2,null);
其中Xinxi方法的代码如下:
public void Xinxi()
{
Console.WriteLine(id + " " + name);
}
Activator类
用于快速实例化对象
用于将Type对象快捷实例化为对象
先得到Type,让快速实例对象
- 有参构造`
Test testobj2=Activator.CreateInstance(testType, 2,"qqq")as Test;
- 无参构造
Type testType = typeof(Test);
Test testobj= Activator.CreateInstance(testType) as Test;
Assembly类
程序集类
用来加载程序集,加载后才能用Type来使用其他程序集的信息
加载同一文件夹下的其他程序集
Assembly asemble2=Assembly.Load(“name”);
加载不同文件夹下的程序集
Assembly asemble2=Assembly.LoadFrom(“包含程序集清单的文件的名称或路径”);
Assembly asemble3=Assembly.LoadFile(“要加载文件的完全限定路径”);
使用过程
Assembly asemble2 = Assembly.LoadFrom(@"E:\c# code\ShuJuJieGou\ListPaiXu\bin\Debug\net5.0\ListPaiXu");
//注意:"\"代表转义字符,在复制路径时要在前面加上"@"取消转义字符的使用
Type[] atypes = asemble2.GetTypes();
foreach(var item in atypes)
{
Console.WriteLine(item);
}
//然后在加载程序集中的一个类对象
Type st = asemble2.GetType("ListPaiXu.ShopItem");
//实例对象
Object spItem= Activator.CreateInstance(st, 2);