反射的使用
反射可以获得Dll里面的类,和对应类的属性,方法,特性,等一系列内容,而不用去添加引用
获得类中的各个内容
如何去添加一个Dll,并且获得对应的类,需要用到一个系统类,Assembly,然后使用Assembly.Load(),来导入Dll文件,然后通过Assembly实例的GetType,来获得类库中的具体类,这里面
的参数需要类的全称,然后根绝methodInfo,Property,field, CustomerAttribute等来获得方法,属性,字段,特性等内容
添加一个基础类Student
public class Student { public Student() { Console.WriteLine("无参构造函数"); } public Student(string name, int age) { Name = name; Age = age; } public string PetName; [DisplayName("姓名")] public string Name { get; set; } public int Age { get; set; } public string Grade() { return "三年级"; } public string Grade(string str) { return "三年级"+ str; } public string GetData(string str) { return str; } public static string StaticFun() { return "Static"; } public static string StaticFun(string str) { return "Static"+str; } public string GetName<T>(T t) { return typeof(T).Name + t.ToString(); } private string GetPrivateFun() { return "Private Fun"; } }
然后在另一个项目中,加载当前Student生成的Dll,来实现反射获取属性
Assembly assembly = Assembly.Load("ReflectClass"); Type type = assembly.GetType("ReflectClass.Student"); foreach (var item in type.GetFields()) { Console.WriteLine(item.Name); } foreach (var item in type.GetMethods()) { Console.WriteLine(item.Name); } foreach (var item in type.GetProperties()) { Console.WriteLine(item.Name); } foreach (var item in type.GetProperty("Name").GetCustomAttributes()) { Console.WriteLine(item.ToString()); } Console.ReadLine();
简单工厂,配置切换代码逻辑
通过反射,咱们可以实现一个简单工厂,来进行配置试的数据库切换,通过面向接口编程,来定义IDBTest接口和DBSqlHelper和DBOracleHelper
public interface IDBTest { string Connection { get; set; } string Add(); string Delete(); string Update(); string Select(); }
public class SqlHelper : IDBTest { public string Connection { get; set; } public string Add() { return "Sql Add"; } public string Delete() { return "Sql Delete"; } public string Select() { return "Sql Select"; } public string Update() { return "Sql Update"; } }
public class OracleHelper : IDBTest { public string Connection { get; set; } public string Add() { return "Oracle Add"; } public string Delete() { return "Oracle Delete"; } public string Select() { return "Oracle Select"; } public string Update() { return "Oracle Update"; } }
简单工厂
public class SimplyFactory { private static string str = System.Configuration.ConfigurationManager.AppSettings["DBHelper"]; private static string aStr = str.Split(',')[0]; private static string tStr = str.Split(',')[1]; public static T Instance<T>() { Assembly assembly = Assembly.Load(aStr); Type type = assembly.GetType(tStr); var helper = (T)Activator.CreateInstance(type); return helper; } }
配置文件
<appSettings> <add key="DBHelper" value="DBHelper,DBHelper.OracleHelper"/> </appSettings>
主方法中,只需要通过以下代码就可以实现数据访问功能的实现,并且在需要求换数据请求逻辑的时候,更新配置文件即可,主函数不需要修改任何代码(面向借口编程)
Console.WriteLine("配置文件简单工厂"); var helper = SimplyFactory.Instance<IDBTest>(); Console.WriteLine(helper.Add()); Console.WriteLine(helper.Delete()); Console.ReadLine();
破坏单例
通过反射还可以调用类中的私有构造函数来破坏单例模式
public class SingleClass { private static SingleClass _singleClass = null; private SingleClass() { Console.WriteLine("singelClass 构造函数"); } static SingleClass() { _singleClass = new SingleClass(); } public static SingleClass GetInstance() { return _singleClass; } }
主函数调用
Assembly assembly = Assembly.Load("ReflectClass"); Type type = assembly.GetType("ReflectClass.SingleClass"); var data1 = Activator.CreateInstance(type, true); Console.ReadLine();
实例化泛型类
public class GenericClass<T,X,M> { public String Show(T t, X x, M m) { return typeof(T).Name + typeof(X).Name + typeof(M).Name; } }
主函数调用(`3 表示是三个泛型参数的类)
Assembly assembly = Assembly.Load("ReflectClass"); Type type = assembly.GetType("ReflectClass.GenericClass`3"); Type type1= type.MakeGenericType(typeof(string), typeof(int), typeof(DateTime)); var data = Activator.CreateInstance(type1); Console.WriteLine();
通过泛型来调用类的私有函数,重载函数,静态函数,泛型函数,(接着使用上面的Student类)
Assembly assembly = Assembly.Load("ReflectClass"); Type type = assembly.GetType("ReflectClass.Student"); var data = Activator.CreateInstance(type); var data1 = Activator.CreateInstance(type, new object[] { "张三", 12 }); //var data2 = Activator.CreateInstance(type, new object[] { 11, "张三"}); MethodInfo method = type.GetMethod("Grade",new Type[] { }); Console.WriteLine(method.Invoke(data1, null)); MethodInfo method1 = type.GetMethod("Grade", new Type[] {typeof(string)}); Console.WriteLine(method1.Invoke(data1, new object[] { "一个参数" })); MethodInfo method2 = type.GetMethod("StaticFun", new Type[] { typeof(string)}); Console.WriteLine(method2.Invoke(null, new object[] { "静态函数一个参数"})); MethodInfo method3 = type.GetMethod("GetName"); MethodInfo method3_1 = method3.MakeGenericMethod(typeof(string)); Console.WriteLine(method3_1.Invoke(data1, new object[] { "泛型" })); MethodInfo method4 = type.GetMethod("GetPrivateFun",BindingFlags.Instance|BindingFlags.NonPublic); Console.WriteLine(method4.Invoke(data1, null)); PropertyInfo proper = type.GetProperty("Name"); Console.WriteLine(proper.GetValue(data1)); proper.SetValue( data1,"李四"); Console.WriteLine(proper.GetValue(data1)); Console.ReadLine();
反射的最大特点就是动态,代码不是写死的,而是可配置的,但是反射的使用会导致一定的性能损耗