目录
涉及知识点: 反射遍历并使用类
一、前期准备
using System;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
二、反射概念
通过工程文件中的dll文件,获取并使用内部的类中所有内容
三、反射加载dll方式
加载一:使用dll文件名
//加载一:使用dll文件名 -- 当前目录 -- 引用->添加引用
Assembly assembly = Assembly.Load("反射");
加载二:使用完整路径名
//加载二:使用完整路径名
Assembly assembly = Assembly.LoadFile(@"C:\\Users\\Rush\\Desktop\\C#\\反射\\bin\\Debug\\netcoreapp3.1\\反射.dll");
加载三:使用完全限定名 --(推荐)
//加载三:使用完全限定名 -- 当前目录 -- 引用->添加引用 --(推荐)
Assembly assembly = Assembly.LoadFrom("反射.dll");
加载四:使用完整路径名
//加载四:使用完整路径名
Assembly assembly = Assembly.LoadFrom(@"C:\\Users\\Rush\\Desktop\\C#\\反射\\bin\\Debug\\netcoreapp3.1\\反射.dll");
四、反射遍历类
1、遍历dll中的类
前期准备:
namespace 反射
{
internal class Program
{
static void Main(string[] args)
{
}
}
//普通类
class Student{}
//泛型类
class Children<T, K, S>{}
//接口
interface ISchool { }
//秘密类
sealed class University { }
//静态类
static class Company { }
}
获取dll中类(包括接口):
GetType("XXX") -- 获取指定类名
GetTypes() -- 获取所有类
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
//遍历dll 所有类(包括接口)
foreach (Type type in assembly.GetTypes())
{
Console.WriteLine(type.Name);
}
}
}
结果显示:
2、遍历类中的各种字段
前期准备:
class Student
{
//↓↓↓↓↓↓↓↓字段↓↓↓↓↓↓↓↓
//内部字段
internal string name;
//受保护字段
protected float grade;
//静态字段
public static int age;
//公开字段
public int id;
//私有字段
private string sex;
}
获取类中的各类型字段:
type.GetField("XXX") ; -- 获取指定字段
type.GetFields(); -- 获取所有字段
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
//遍历dll 所有类(包括接口)
foreach (Type type in assembly.GetTypes())
{
//显示类名
Console.WriteLine($"类名:{type.Name}");
//遍历所有公开字段
foreach (FieldInfo field in type.GetFields())
{
Console.WriteLine($"字段类型:{field.FieldType.Name} " +
$"字段名:{field.Name}");
}
//遍历所有私有字段
foreach (FieldInfo privateField in type.GetFields(BindingFlags.Instance
| BindingFlags.NonPublic))
{
Console.WriteLine($"私有 -- " +
$"字段类型{privateField.FieldType.Name} " +
$"字段名:{privateField.Name}");
}
}
}
}
结果显示:
3、遍历类中的各种属性
前期准备:
class Student
{
//↓↓↓↓↓↓↓↓属性↓↓↓↓↓↓↓↓
//内部属性
internal string Sex { get; set; }
//受保护属性
protected int Id { get; set; }
//公共属性
public int Age { get; set; }
//静态属性
public static float Grade { get; set; }
//私有属性
private string Hobby { get; set; }
}
获取dll中类(包括接口):
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
//遍历dll 所有类(包括接口)
foreach (Type type in assembly.GetTypes())
{
//显示类名
Console.WriteLine($"类名:{type.Name}");
//遍历所有公开属性
foreach (PropertyInfo property in type.GetProperties())
{
Console.WriteLine($"属性类型:{property.PropertyType.Name} " +
$"属性名:{property.Name}");
}
//遍历所有私有属性
foreach (PropertyInfo privateField in type.GetProperties(
BindingFlags.Instance | BindingFlags.NonPublic))
{
Console.WriteLine($"私有 -- " +
$"属性类型{privateField.PropertyType.Name} " +
$"属性名:{privateField.Name}");
}
}
}
}
结果显示:
4、遍历类中的各种方法
前期准备:
class Student
{
//↓↓↓↓↓↓↓↓构造方法↓↓↓↓↓↓↓↓
public Student() { }
internal Student(int id) { }
protected Student(int id, string sex) { }
private Student(int id, string sex, float grade) { }
//↓↓↓↓↓↓↓↓重构方法↓↓↓↓↓↓↓↓
public void Music() { }
internal void Music(int id) { }
protected void Music(int id, string name) { }
private void Music(int id, string name, float grade) { }
//↓↓↓↓↓↓↓↓泛型方法↓↓↓↓↓↓↓↓
public void Math<T>() { }
public void Art<T>(T t) { }
//↓↓↓↓↓↓↓↓静态方法↓↓↓↓↓↓↓↓
public static void Chinese() { }
//↓↓↓↓↓↓↓↓普通方法↓↓↓↓↓↓↓↓
public int English() => 10;
}
获取dll中类(包括接口):
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
//遍历dll 所有类(包括接口)
foreach (Type type in assembly.GetTypes())
{
//显示类名
Console.WriteLine($"类名:{type.Name}");
//遍历所有公共的方法
foreach (MethodInfo method in type.GetMethods())
{
Console.Write($"方法: {method.ReturnType.Name} " +
$"{method.Name}");
if (method.GetParameters().Length == 0)
{
Console.WriteLine("();");
continue;
}
foreach (ParameterInfo parameter in method.GetParameters())
{
Console.Write($"({parameter.ParameterType.Name} " +
$"{parameter.Name});");
}
Console.WriteLine();
}
//遍历所有受保护的方法
foreach (MethodInfo privateMethod in type.GetMethods(
BindingFlags.Instance
| BindingFlags.NonPublic))
{
Console.Write($"受保护方法: {privateMethod.ReturnType.Name} " +
$"{privateMethod.Name}");
if (privateMethod.GetParameters().Length == 0)
{
Console.WriteLine("();");
continue;
}
foreach (ParameterInfo parameter in privateMethod.GetParameters())
{
Console.Write($"({parameter.ParameterType.Name} " +
$"{parameter.Name});");
}
Console.WriteLine();
}
//遍历所有构造方法
foreach (ConstructorInfo constructor in type.GetConstructors())
{
Console.Write($"构造方法: {constructor.Name}");
if (constructor.GetParameters().Length == 0)
{
Console.WriteLine("();");
continue;
}
foreach (ParameterInfo parameter in constructor.GetParameters())
{
Console.Write($"({parameter.ParameterType.Name} " +
$"{parameter.Name});");
}
Console.WriteLine();
}
//遍历所有受保护的构造方法
foreach (ConstructorInfo constructor in type.GetConstructors(
BindingFlags.Instance
| BindingFlags.NonPublic))
{
Console.Write($"受保护的构造方法: {constructor.Name}");
if (constructor.GetParameters().Length == 0)
{
Console.WriteLine("();");
continue;
}
foreach (ParameterInfo parameter in constructor.GetParameters())
{
Console.Write($"({parameter.ParameterType.Name} " +
$"{parameter.Name});");
}
Console.WriteLine();
}
}
}
}
结果显示:
五、类中值的应用
1、字段的使用
前期准备:
class Student
{
//↓↓↓↓↓↓↓↓字段↓↓↓↓↓↓↓↓
//公共字段
public int id;
//静态字段
public static int age;
//内部字段
internal string name;
//受保护字段
protected float grade;
//私有字段
private string sex;
}
字段应用:
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
Type studentClass = assembly.GetType("反射.Student");
object studentObject = Activator.CreateInstance(studentClass);
//公共字段
FieldInfo idField = studentClass.GetField("id");
idField.SetValue(studentObject, 2);
Console.WriteLine(idField.GetValue(studentObject));
//公共静态字段
//!!!设置时: studentObject 可以用 null 代替
FieldInfo ageField = studentClass.GetField("age");
ageField.SetValue(null, 3);
Console.WriteLine(ageField.GetValue(null));
//-----------------私有字段创建---------------------------
Type studentPrivateClass = assembly.GetType("反射.Student");
object studentPrivateObject = Activator.CreateInstance(studentPrivateClass);
//内部字段
FieldInfo nameField = studentPrivateClass.GetField("name",
BindingFlags.Instance
| BindingFlags.NonPublic);
nameField.SetValue(studentPrivateObject, "小王");
Console.WriteLine(nameField.GetValue(studentPrivateObject));
//受保护字段
FieldInfo gradeField = studentPrivateClass.GetField("grade",
BindingFlags.Instance
| BindingFlags.NonPublic);
gradeField.SetValue(studentPrivateObject, 95.6f);
Console.WriteLine(gradeField.GetValue(studentPrivateObject));
//私有字段
FieldInfo sexField = studentPrivateClass.GetField("sex",
BindingFlags.Instance
| BindingFlags.NonPublic);
sexField.SetValue(studentPrivateObject, "男");
Console.WriteLine(sexField.GetValue(studentPrivateObject));
}
}
结果显示:
2、属性的使用
前期准备:
class Student
{
//↓↓↓↓↓↓↓↓属性↓↓↓↓↓↓↓↓
//公共属性
public int Id { get; set; }
//公共静态属性
public static string Name { get; set; }
//内部属性
internal string Sex { get; set; }
//受保护属性
protected float Grade { get; set; }
//私有属性
private string Hobby { get; set; }
}
属性应用:
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
Type studentClass = assembly.GetType("反射.Student");
Object studentObject = Activator.CreateInstance(studentClass);
//公共属性
PropertyInfo idProperty = studentClass.GetProperty("Id");
idProperty.SetValue(studentObject, 2);
Console.WriteLine(idProperty.GetValue(studentObject));
//公共静态属性
//!!!静态时: studentObject 可以用 null 代替
PropertyInfo nameProperty = studentClass.GetProperty("Name");
nameProperty.SetValue(null, "小王");
Console.WriteLine(nameProperty.GetValue(null));
//-----------------私有字段创建-------------------------- -
Type studentPrivateClass = assembly.GetType("反射.Student");
object studentPrivateObject = Activator.CreateInstance(studentPrivateClass);
//内部属性
PropertyInfo sexProperty = studentPrivateClass.GetProperty("Sex",
BindingFlags.Instance
| BindingFlags.NonPublic);
sexProperty.SetValue(studentPrivateObject, "男");
Console.WriteLine(sexProperty.GetValue(studentPrivateObject));
//受保护属性
PropertyInfo gradeProperty = studentPrivateClass.GetProperty("Grade",
BindingFlags.Instance
| BindingFlags.NonPublic);
gradeProperty.SetValue(studentPrivateObject, 99.6f);
Console.WriteLine(gradeProperty.GetValue(studentPrivateObject));
//受私有属性
PropertyInfo hobbyProperty = studentPrivateClass.GetProperty("Hobby",
BindingFlags.Instance
| BindingFlags.NonPublic);
hobbyProperty.SetValue(studentPrivateObject, "打羽毛球");
Console.WriteLine(hobbyProperty.GetValue(studentPrivateObject));
}
}
结果显示:
3、方法的使用
1、构造方法
前期准备:
class Student
{
//↓↓↓↓↓↓↓↓构造方法↓↓↓↓↓↓↓↓
public Student()
=> Console.WriteLine("public 无参构造");
internal Student(int id)
=> Console.WriteLine("internal 一个参数构造");
protected Student(int id, string sex)
=> Console.WriteLine("protected 两个参数构造");
private Student(int id, string sex, float grade)
=> Console.WriteLine("private 三个参数构造");
}
构造方法应用:
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
//获取Student类
Type studentClass = assembly.GetType("反射.Student");
//实例化创建Student类
object studentObject = Activator.CreateInstance(studentClass);
//public 无参构造
ConstructorInfo studentConstructor = studentClass
.GetConstructor(Type.EmptyTypes);
studentConstructor.Invoke(studentObject, null);
//实例化创建Student类
object studentObject_1 = Activator.CreateInstance(studentClass, true);
//internal 一个参数构造
ConstructorInfo studentConstructor_1 = studentClass
.GetConstructor(
BindingFlags.Instance
| BindingFlags.NonPublic, null,
new Type[] { typeof(int) }, null);
studentConstructor_1.Invoke(new object[] { 2 });
//实例化创建Student类
object studentObject_2 = Activator.CreateInstance(studentClass, true);
//protected 两个参数构造
ConstructorInfo studentConstructor_2 = studentClass
.GetConstructor(
BindingFlags.Instance
| BindingFlags.NonPublic, null,
new Type[] { typeof(int),
typeof(string) }, null);
studentConstructor_2.Invoke(new object[] { 2, "abc" });
//实例化创建Student类
object studentObject_3 = Activator.CreateInstance(studentClass, true);
//private 三个参数构造
ConstructorInfo studentConstructor_3 = studentClass
.GetConstructor(
BindingFlags.Instance
| BindingFlags.NonPublic, null,
new Type[] { typeof(int),
typeof(string), typeof(float)}, null);
studentConstructor_3.Invoke(new object[] { 2, "abc", 3.4f });
}
}
结果显示:
2、重构方法
前期准备:
class Student
{
//↓↓↓↓↓↓↓↓重构方法↓↓↓↓↓↓↓↓
public void Music()
=> Console.WriteLine("public 无参重构");
internal void Music(int id)
=> Console.WriteLine("internal 一个参数重构");
protected void Music(int id, string sex)
=> Console.WriteLine("protected 两个参数重构");
private void Music(int id, string sex, float grade)
=> Console.WriteLine("private 三个参数重构");
}
重构方法应用:
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
//获取Student类
Type studentClass = assembly.GetType("反射.Student");
//实例化创建Student类
object studentObject = Activator.CreateInstance(studentClass);
//public 无参构造
MethodInfo MusicMethod = studentClass.GetMethod("Music");
MusicMethod.Invoke(studentObject, null);
//internal 一个参构造
MethodInfo MusicMethod_1 = studentClass.GetMethod("Music",
BindingFlags.Instance
| BindingFlags.NonPublic,
null,
new Type[] { typeof(int)},
null);
MusicMethod_1.Invoke( studentObject,new object[] { 2 });
//protected 两个个参构造
MethodInfo MusicMethod_2 = studentClass.GetMethod("Music",
BindingFlags.Instance
| BindingFlags.NonPublic,
null,
new Type[] { typeof(int), typeof(string) },
null);
MusicMethod_2.Invoke(studentObject, new object[] { 2, "abc" });
//private 三个参构造
MethodInfo MusicMethod_3 = studentClass.GetMethod("Music",
BindingFlags.Instance
| BindingFlags.NonPublic,
null,
new Type[] { typeof(int), typeof(string), typeof(float) },
null);
MusicMethod_3.Invoke(studentObject, new object[] { 2, "abc", 3.4f });
}
}
结果显示:
3、泛型方法
前期准备:
class Student
{
//↓↓↓↓↓↓↓↓泛型方法↓↓↓↓↓↓↓↓
public void Music<T>() => Console.WriteLine("public 无参泛型");
internal void Art<T>(T id) => Console.WriteLine("internal 一个参数泛型");
protected void Math<T>(T id) => Console.WriteLine("protected 一个参数泛型");
private void Chinese<T>(T id) => Console.WriteLine("private 一个参数泛型");
}
泛型方法应用:
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
//获取Student类
Type studentClass = assembly.GetType("反射.Student");
//实例化创建Student类
object studentObject = Activator.CreateInstance(studentClass);
//public 无参泛型方法
MethodInfo MusicMethod = studentClass.GetMethod("Music",Type.EmptyTypes);
MethodInfo Music = MusicMethod.MakeGenericMethod(studentClass);
Music.Invoke(studentObject, null);
//internal 一个参数泛型方法
MethodInfo ArtMethod = studentClass.GetMethod("Art",
BindingFlags.Instance
| BindingFlags.NonPublic);
MethodInfo Art = ArtMethod.MakeGenericMethod(new Type[] { typeof(int)});
Art.Invoke(studentObject, new object[] { 2 });
//protected 一个参数泛型方法
MethodInfo MathMethod = studentClass.GetMethod("Math",
BindingFlags.Instance
| BindingFlags.NonPublic);
MethodInfo Math = MathMethod.MakeGenericMethod(new Type[] { typeof(int) });
Math.Invoke(studentObject, new object[] { 2 });
//private 一个参数泛型方法
MethodInfo ChineseMethod= studentClass.GetMethod("Chinese",
BindingFlags.Instance
| BindingFlags.NonPublic);
MethodInfo Chinese = ChineseMethod.MakeGenericMethod(
new Type[] { typeof(int)});
Chinese.Invoke(studentObject, new object[] { 2 });
}
}
结果显示:
4、普通方法
前期准备:
class Student
{
//↓↓↓↓↓↓↓↓普通方法↓↓↓↓↓↓↓↓
public void Music() => Console.WriteLine("public 无参方法");
public static int English()
{
Console.WriteLine("public static 无参方法");
return 2;
}
internal void Art(int id) => Console.WriteLine("internal 一个参数方法");
protected void Math(int id) => Console.WriteLine("protected 一个参数方法");
private void Chinese(int id) => Console.WriteLine("private 一个参数方法");
}
普通方法应用:
internal class Program
{
static void Main(string[] args)
{
//加载dll
Assembly assembly = Assembly.LoadFrom("反射.dll");
//获取Student类
Type studentClass = assembly.GetType("反射.Student");
//实例化创建Student类
object studentObject = Activator.CreateInstance(studentClass);
//public 无参方法
MethodInfo MusicMethod = studentClass.GetMethod("Music", Type.EmptyTypes);
MusicMethod.Invoke(studentObject, null);
//public static 静态无参方法
//!!!静态时: studentObject 可以用 null 代替
MethodInfo EnglishMethod = studentClass.GetMethod("English",
Type.EmptyTypes);
Console.WriteLine(EnglishMethod.Invoke(null, null).ToString());
//internal 一个参数方法
MethodInfo ArtMethod = studentClass.GetMethod("Art",BindingFlags.Instance
| BindingFlags.NonPublic,null,
new Type[] { typeof(int) },null);
ArtMethod.Invoke(studentObject, new object[] { 2 });
//protected 一个参数方法
MethodInfo MathMethod = studentClass.GetMethod("Math", BindingFlags.Instance
| BindingFlags.NonPublic, null,
new Type[] { typeof(int) },
null);
MathMethod.Invoke(studentObject, new object[] { 2 });
//private 一个参数方法
MethodInfo ChineseMethod = studentClass.GetMethod("Chinese",
BindingFlags.Instance
| BindingFlags.NonPublic,
null,
new Type[] { typeof(int) },
null);
ChineseMethod.Invoke(studentObject, new object[] { 2 });
}
}
结果显示:
如有错误,烦请批评指正