(精华)2020年8月9日 C#基础知识点 反射
(精华)2020年8月9日 C#基础知识点 反射
原理图
/// <summary>
/// 1 dll-IL-metadata-反射
/// 2 反射加载dll,读取module、类、方法
/// 3 反射创建对象,反射+简单工厂+配置文件 ,破坏单例 创建泛型
/// 反射反射程序员的快乐
/// 反射是无处不在,MVC AOP IOC ORM Attribute
/// IL:中间语言,标准的面向对象语言,但是不太好阅读
/// metadata:元数据, 数据清单,只是描述了类中有什么
/// 反射:Reflection, System.Reflection命名空间,是微软提供的一个帮助类库
/// </summary>
class Program
{<!-- -->
static void Main(string[] args)
{<!-- -->
try
{<!-- -->
#region 反射的基本使用
{<!-- -->
//-------------------------- 1、动态加载(获取程序集的数据)--------------------------
Assembly assembly = Assembly.Load("DB.SqlServer");// dll名称 默认到当前目录下查找
Assembly assembly1 = Assembly.LoadFile(@"D:\MyReflection\bin\Debug\DB.SqlServer.dll");// 全名称= 全路径+dll名称 + 后缀
Assembly assembly2 = Assembly.LoadFrom("DB.SqlServer.dll");// 全名称
Assembly assembly3 = Assembly.LoadFrom(@"D:\MyReflection\bin\Debug\DB.SqlServer.dll");// 全名称
foreach (Type type in assembly.GetTypes())
{<!-- -->
Console.WriteLine(type.Name);
foreach (MethodInfo method in type.GetMethods())
{<!-- -->
Console.WriteLine(method.Name);
}
}
}
{<!-- -->
//------------------------1、动态加载(使用程序集的数据创建实例和使用)-----------------------------
Assembly assembly = Assembly.Load("DB.SqlServer");// dll名称 默认到当前目录下查找
//2、获取类型
Type type = assembly.GetType("DB.SqlServer.SqlServerHelper");
//3、创建对象
object oDbHelper = Activator.CreateInstance(type);
//oDbHelper.Query();// 编译器就不认可 c# 是强类型语言,不能Query
//dynamic dDbHelper = Activator.CreateInstance(type);
//dDbHelper.Query(); //dynamic 是一个动态类型,可以避开编译器的检查,运行时检查 存在安全问题
//4、类型转换
IDBHelper iDBHelper = oDbHelper as IDBHelper;
//5、调用方法
iDBHelper.Query();
}
{<!-- --> //---------------------------用工厂创建实例---------------------------
IDBHelper iDBHelper = SimlpFactory.CreateInstentce();
iDBHelper.Query();
}
{<!-- -->
//-------------------------反射选择不同的构造函数创建对象----------------------
Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.ReflectionTest");
object oDbHelper = Activator.CreateInstance(type);
object oDbHelper1 = Activator.CreateInstance(type, new object[] {<!-- --> "杰克" });
object oDbHelper2 = Activator.CreateInstance(type, new object[] {<!-- --> "我是谁" });
object oDbHelper3 = Activator.CreateInstance(type, new object[] {<!-- --> 123 });
}
{<!-- -->
//--------------------反射需要先获取方法,然后方法Invoke--------------------
Assembly assembly = Assembly.Load("DB.SqlServer");
Type type = assembly.GetType("DB.SqlServer.ReflectionTest");
object oTest = Activator.CreateInstance(type);
MethodInfo show1 = type.GetMethod("Show1");
show1.Invoke(oTest, new object[0]);// 反射调用方法
MethodInfo show2 = type.GetMethod("Show2");
show2.Invoke(oTest, new object[] {<!-- --> 123 });// 反射调用方法 ,需要参数的时候,参数类型必须和方法参数类型保持一致
//重载方法:
MethodInfo show3 = type.GetMethod("Show3", new Type[] {<!-- --> typeof(string), typeof(int) });
show3.Invoke(oTest, new object[] {<!-- --> "飞哥", 134 });// 反射调用方法
MethodInfo show4 = type.GetMethod("Show4", BindingFlags.NonPublic | BindingFlags.CreateInstance);
show4.Invoke(oTest, new object[] {<!-- --> "Tenk" });// 反射调用方法
MethodInfo show5 = type.GetMethod("Show5");
show5.Invoke(oTest, new object[] {<!-- --> "彭于晏" });// 反射调用静态方法: 对象的实例 可以传入,也可以传入null
show5.Invoke(null, new object[] {<!-- --> "Korey" });
}
{<!-- -->
//---------------反射调用泛型相关------------------------------
//泛型编译之后生成展位符 `1 `2 `3
Assembly assembly = Assembly.Load("DB.SqlServer");
Type type = assembly.GetType("DB.SqlServer.GenericMethod");
object oTest = Activator.CreateInstance(type);
MethodInfo genericMethod = type.GetMethod("Show");
MethodInfo genericMethod1 = genericMethod.MakeGenericMethod(new Type[] {<!-- --> typeof(int), typeof(string), typeof(DateTime) });// 指定泛型方法的 具体参数
genericMethod1.Invoke(oTest, new object[] {<!-- --> 123, "jun", DateTime.Now }); // 传入参数必须和声明的一样
//在泛型类中 调用泛型方法
Assembly assembly = Assembly.Load("DB.SqlServer");
Type type = assembly.GetType("DB.SqlServer.GenericClass`3"); //获取一个泛型类型
// GenericClass<int,string,DateTime> genericClass = new GenericClass<int, string, DateTime>()
Type type1 = type.MakeGenericType(new Type[] {<!-- --> typeof(int), typeof(string), typeof(DateTime) });
object oGenericTest = Activator.CreateInstance(type1);
MethodInfo genericMethod = type1.GetMethod("Show");
genericMethod.Invoke(oGenericTest, new object[] {<!-- --> 123, "零零", DateTime.Now });
}
{<!-- -->
//-----------------反射破坏单利 其实就是反射调用私有构造函数-------------------
Singleton singleton = new Singleton();
Singleton singleton1 = Singleton.GetInstance();
Singleton singleton2 = Singleton.GetInstance();
Singleton singleton3 = Singleton.GetInstance();
Singleton singleton4 = Singleton.GetInstance();
Console.WriteLine(singleton1.Equals(singleton4));
Assembly assembly = Assembly.Load("DB.SqlServer");
Type type = assembly.GetType("DB.SqlServer.Singleton");
object oSingleton1 = Activator.CreateInstance(type, true); //完全等价于 New Singleton
object oSingleton2 = Activator.CreateInstance(type, true);
object oSingleton3 = Activator.CreateInstance(type, true);
object oSingleton4 = Activator.CreateInstance(type, true);
Console.WriteLine(oSingleton1.Equals(oSingleton4));
}
{<!-- -->
//-----------------------反射使用属性字段----------------
People people = new People();
people.Id = 123;
people.Name = "零零";
people.Description = "啦啦啦";
Console.WriteLine($"people.Id={people.Id}");
Console.WriteLine($"people.Name={people.Name}");
Console.WriteLine($"people.Description={people.Description}");
// 1、GetValue其实是有意义的
// 2、SetValue 好像没啥用
Type type = typeof(People);
object oPeople = Activator.CreateInstance(type);
foreach (PropertyInfo prop in type.GetProperties())
{<!-- -->
if (prop.Name.Equals("Id"))
{<!-- -->
prop.SetValue(oPeople, 123);
}
else if (prop.Name.Equals("Name"))
{<!-- -->
prop.SetValue(oPeople, "零零");
}
Console.WriteLine($"oPeople.{prop.Name}={prop.GetValue(oPeople)}");
}
foreach (FieldInfo field in type.GetFields())
{<!-- -->
if (field.Name.Equals("Description"))
{<!-- -->
field.SetValue(oPeople, "啦啦啦");
}
}
}
#endregion
}
catch (Exception ex)
{<!-- -->
Console.WriteLine(ex.Message);
}
Console.Read();
}
}
public class SimlpFactory
{<!-- -->
private static string IDBHelperConfig = ConfigurationManager.AppSettings["IDBHelperConfig"];
private static string DllName = IDBHelperConfig.Split(',')[1];
private static string TypeName = IDBHelperConfig.Split(',')[0];
public static IDBHelper CreateInstentce()
{<!-- -->
Assembly assembly = Assembly.Load(DllName);
Type type = assembly.GetType(TypeName);
object oDbHelper = Activator.CreateInstance(type);
return oDbHelper as IDBHelper;
}
}