字数
1344 字
阅读时间
6 分钟
- 程序集:经由编译器编译得到的,供进一步编译执行的那个中间产物。在WINDOWS系统中,它一般表现为后缀为.dll(库文件)或者是.exe(可执行文件)的格式
- 元数据:程序中的类,类中的函数、变量等信息。有关程序以及类型的数据被称为元数据,它们保存在程序集中
- 反射:在程序运行时,通过反射可以得到其它程序集或者自己程序集代码的各种信息。类,函数,变量,对象等等,实例化它们,执行它们,操作它们
获取Type
- 万物之父object中的 GetType()可以获取对象的Type
cs
int a = 42;
Type type = a.GetType();
- 通过typeof关键字 传入类名 也可以得到对象的Type
cs
Type type2 = typeof(int);
- 通过类的名字 也可以获取类型 类名必须包含命名空间 不然找不到
cs
Type type3 = Type.GetType("System.Int32");
得到类的程序集信息
.Assembly
cs
Console.WriteLine(type.Assembly);
获取类中的所有公共成员
cs
Type t = typeof(Test);
//.GetMembers()得到所有公共成员
//引用命名空间 using System.Reflection;
MemberInfo[] infos = t.GetMembers();
for(int i = 0; i < infos.Length; i++)
{
Console.WriteLine(infos[i]);
}
获取类的公共构造函数并调用
获取所有构造函数
cs
ConstructorInfo[] ctors = t.GetConstructors();
获取其中一个构造函数并执行
在C#中,使用反射获取构造函数时,需要使用数组的形式传递参数类型。GetConstructor方法的签名要求传递一个Type数组,以便正确匹配构造函数的参数类型。构造函数可能有多个重载,使用数组可以明确指定要匹配的参数类型。如果不喜欢显式地创建数组,可以使用更简洁的语法,例如:
cs
ConstructorInfo info = t.GetConstructor(Type.EmptyTypes);
ConstructorInfo info2 = t.GetConstructor(new[] { typeof(int) });
ConstructorInfo info3 = t.GetConstructor(new[] { typeof(int), typeof(string) });
- 无参构造
cs
ConstructorInfo info = t.GetConstructor(new Type[0]);
Test obj = info.Invoke(null) as Test;
- 有参构造
cs
ConstructorInfo info2 = t.GetConstructor(new Type[]{ typeof(int) });
obj = info2.Invoke(new object[] { 2 }) as Test;
- 多参
cs
ConstructorInfo info3 = t.GetConstructor(new Type[] { typeof(int), typeof(string) });
obj = info3.Invoke(new object { 4, "44444" }) as Test;
Console.WriteLine(obj.str);
获取类的公共成员变量
- 得到所有成员变量
cs
FieldInfo[] fieldInfos = t.GetFields();
- 得到指定名称的公共成员变量
cs
FieldInfo infoJ = t.GetField("j");
- 通过反射获取和设置对象的值
cs
Test test = new Test();
test.j = 99;
test.str = "222";
Console.WriteLine(infoJ.GetValue(test));
//输出99
infoJ.SetValue(test, 100);
Console.WriteLine(infoJ.GetValue(test));
//输出100
获取类的公共成员方法
cs
Type strType = typeof(string);
MethodInfo[] methods = strType.GetMethods();
for (int i = 0; i < methods.Length; i++)
{
Console.WriteLine(methods[i]);
}
1.如果存在方法重载用Type数组表示参数类型
cs
MethodInfo subStr = strType.GetMethod("Substring", new Type[] { typeof(int), typeof(int) });
2.调用该方法 注意:如果是静态方法,Invoke中的第一个参数传null即可
cs
string str = "Hello,World!";
//第一个参数:哪个对象要执行这个成员方法
object result = subStr.Invoke(str, new object[] { 7, 5 });
Console.WriteLine(result);
//输出:orld (从第7位置截取5个字符)
其他 Type 接口
得枚举
cs
GetEnumName
GetEnumNames
得事件
cs
GetEvent
GetEvents
得接口
cs
GetInterface
GetInterfaces
得属性
cs
GetProperty
GetPropertys
附:Test类:
cs
class Test
{
private int i = 1;
public int j = 0;
public string str = "123";
public Test()
{
}
public Test(int i)
{
this.i = i;
}
public Test( int i, string str ):this(i)
{
this.str = str;
}
public void Speak()
{
Console.WriteLine(i);
}
}
Activator
Activator:用于快速实例化对象的类
cs
Type testType = typeof(Test);
//无参构造
Test testObj = Activator.CreateInstance(testType) as Test;
//有参构造
testObj= Activator.CreateInstance(testType, 99) as Test;
//多参数
testObj= Activator.CreateInstance(testType, 99, "123") as Test;
Assembly:程序集类
主要用来加载其它程序集,加载后才能用 Type 来使用其它程序集中的信息 如果想要使用不是自己程序集中的内容需要先加载程序集,比如 dll 文件 (库文件) 简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类
三种加载程序集的函数
cs
//一般用来加载在同一文件下的其它程序集
Assembly asembly2 = Assembly.Load ("程序集名称");
//一般用来加载不在同一文件下的其它程序集
//.dll后缀不用写于路径中
Assembly asembly = Assembly.LoadFrom ("包含程序集清单的文件的名称或路径");
Assembly asembly3 = Assembly.LoadFile ("要加载的文件的完全限定路径");
- 先加载一个指定程序集
cs
Assembly asembly = Assembly.LoadFrom (@"C:\Users\MECHREVO\Desktop\CSharp 进阶教学\Lesson 18_练习题\bin\Debug\netcoreapp 3.1\Lesson 18_练习题");
Type[] types = asembly.GetTypes ();
For (int i = 0; i < types. Length; i++)
{
Console.WriteLine (types[i]);
}
- 再加载程序集中的一个类对象之后才能使用反射
cs
Type icon = asembly.GetType ("Lesson 18_练习题. Icon");
MemberInfo[] members = icon.GetMembers ();
For (int i = 0; i < members. Length; i++)
{
Console.WriteLine (members[i]);
}
//通过反射实例化一个 icon 对象
//首先得到枚举 Type 来得到可以传入的参数
Type moveDir = asembly.GetType ("Lesson 18_练习题. E_MoveDir");
FieldInfo right = moveDir.GetField ("Right");
//直接实例化对象
//没有Icon类,所以用万物之父Object装载
Object iconObj = Activator.CreateInstance (icon, 10, 5, right.GetValue (null));
//得到对象中的方法通过反射
MethodInfo move = icon.GetMethod ("Move");
MethodInfo draw = icon.GetMethod ("Draw");
MethodInfo clear = icon.GetMethod ("Clear");
贡献者
worldddddd