C#高级特性(反射)

  • A+
所属分类:.NET技术
摘要

今天来讲解反射的应用:简诉一下,反射就是.Net Framework 的一个帮助类库,可以获取并使用metadata(元数据清单);说的通俗易懂点,就是不用通过引用,仍然可以使用其他层的类。

今天来讲解反射的应用:

一、反射是什么?

简诉一下,反射就是.Net Framework 的一个帮助类库,可以获取并使用metadata(元数据清单);说的通俗易懂点,就是不用通过引用,仍然可以使用其他层的类。

二、让我们建一个项目来开始操作吧!!!

1、建立一个控制台应用程序,并建立一个类库,类库里添加一个用户类。

C#高级特性(反射)

public class UsersInfo     {         public string Name { get; set; }         public bool Sex { get; set; }         public void CommonMethod()         {             Console.WriteLine("我是普通方法");         }         public void ParameterMethod(string name)         {             Console.WriteLine("我是带参数方法,我叫"+name);         }          public void OverrideMethod(int age)         {             Console.WriteLine("我是重载方法,我今年"+age);         }         public void OverrideMethod(string name)         {             Console.WriteLine("我是重载方法,我叫" + name);         }         public void GenericityMethod<T>(T t)         {             Console.WriteLine("我是泛型方法方法,类型是"+typeof(T));         }         private void PrivateMethod()         {             Console.WriteLine("我是私有方法");         }         public static void StaticMethod()         {             Console.WriteLine("我是静态方法");         }     } 

2、利用反射获取类库,和类

  • 第一步引用命名空间
  • 第二步,动态加载类库,写要获取类库的绝对路径
  • 第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection;//第一步引用命名空间 namespace Reflection {     class Program     {         static void Main(string[] args)         {             {                 //第二步,动态加载类库,写要获取类库的绝对路径                 Assembly assembly= Assembly.LoadFile(@"C:Users炸天张缺缺DesktopReflectionReflection.ModelbinDebugReflection.Model.dll");                 //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀                 Type type = assembly.GetType("Reflection.Model.UsersInfo");                 Console.WriteLine(type.Name);                              }         }     } }  

C#高级特性(反射)

3、利用反射获取属性,和属性类型

  • 遍历类型的属性集合
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection;//第一步引用命名空间 namespace Reflection {     class Program     {         static void Main(string[] args)         {             {                 Console.WriteLine("***********************获取类*****************************");                 //第二步,动态加载类库,写要获取类库的绝对路径                 Assembly assembly= Assembly.LoadFile(@"C:Users炸天张缺缺DesktopReflectionReflection.ModelbinDebugReflection.Model.dll");                 //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀                 Type type = assembly.GetType("Reflection.Model.UsersInfo");                 Console.WriteLine(type.Name);                 Console.WriteLine("***********************获取属性*****************************");                 //遍历类型的属性集合                 foreach (var item in type.GetProperties())                 {                     Console.WriteLine(item.Name+"   "+item.PropertyType);                 }             }                                                   }     } }  

三、获取方法(方法类型比较多,所以单独做个模块来写)

  • 创建一个符合类型的对象
  • 指定要获取的方法名称
  • 创建方法,第一个参数,对象,第二个参数,没有则为空

1、获取普通方法

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection;//第一步引用命名空间 namespace Reflection {     class Program     {         static void Main(string[] args)         {             {                 Console.WriteLine("***********************获取类*****************************");                 //第二步,动态加载类库,写要获取类库的绝对路径                 Assembly assembly= Assembly.LoadFile(@"C:Users炸天张缺缺DesktopReflectionReflection.ModelbinDebugReflection.Model.dll");                 //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀                 Type type = assembly.GetType("Reflection.Model.UsersInfo");                 Console.WriteLine(type.Name);                 Console.WriteLine("***********************获取属性*****************************");                 //遍历类型的属性集合                 foreach (var item in type.GetProperties())                 {                     Console.WriteLine(item.Name+"   "+item.PropertyType);                 }                 Console.WriteLine("***********************普通方法*****************************");                 object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象                 MethodInfo method = type.GetMethod("CommonMethod");//指定要获取的方法名称                 method.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空             }                                                   }     } }  

C#高级特性(反射)

2、获取带参数的方法

  • 指定要获取的方法名称
  • 创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection;//第一步引用命名空间 namespace Reflection {     class Program     {         static void Main(string[] args)         {             {                 Console.WriteLine("***********************获取类*****************************");                 //第二步,动态加载类库,写要获取类库的绝对路径                 Assembly assembly= Assembly.LoadFile(@"C:Users炸天张缺缺DesktopReflectionReflection.ModelbinDebugReflection.Model.dll");                 //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀                 Type type = assembly.GetType("Reflection.Model.UsersInfo");                 Console.WriteLine(type.Name);                 Console.WriteLine("***********************获取属性*****************************");                 //遍历类型的属性集合                 foreach (var item in type.GetProperties())                 {                     Console.WriteLine(item.Name+"   "+item.PropertyType);                 }                  Console.WriteLine("***********************普通方法*****************************");                 object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象                 MethodInfo commonMethod = type.GetMethod("CommonMethod");//指定要获取的方法名称                 commonMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空                  Console.WriteLine("***********************带参数的方法*****************************");                 MethodInfo parameterMethod = type.GetMethod("ParameterMethod");//指定要获取的方法名称                 parameterMethod.Invoke(oUser, new object[] { "餐餐"});//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型             }                                                   }     } }  

C#高级特性(反射)

3、重载方法

  • 指定要获取的方法名称,和参数类型
  • 创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection;//第一步引用命名空间 namespace Reflection {     class Program     {         static void Main(string[] args)         {             {                 Console.WriteLine("***********************获取类*****************************");                 //第二步,动态加载类库,写要获取类库的绝对路径                 Assembly assembly= Assembly.LoadFile(@"C:Users炸天张缺缺DesktopReflectionReflection.ModelbinDebugReflection.Model.dll");                 //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀                 Type type = assembly.GetType("Reflection.Model.UsersInfo");                 Console.WriteLine(type.Name);                 Console.WriteLine("***********************获取属性*****************************");                 //遍历类型的属性集合                 foreach (var item in type.GetProperties())                 {                     Console.WriteLine(item.Name+"   "+item.PropertyType);                 }                  Console.WriteLine("***********************普通方法*****************************");                 object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象                 MethodInfo commonMethod = type.GetMethod("CommonMethod");//指定要获取的方法名称                 commonMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空                  Console.WriteLine("***********************带参数的方法*****************************");                 MethodInfo parameterMethod = type.GetMethod("ParameterMethod");//指定要获取的方法名称                 parameterMethod.Invoke(oUser, new object[] { "餐餐"});//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型                  Console.WriteLine("***********************重载方法int参数*****************************");                 MethodInfo overrideMethodInt = type.GetMethod("OverrideMethod",new Type[] { typeof(int)});//指定要获取的方法名称,和参数类型                 overrideMethodInt.Invoke(oUser, new object[] { 18 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型                  Console.WriteLine("***********************重载方法string参数*****************************");                 MethodInfo overrideMethodStrint = type.GetMethod("OverrideMethod", new Type[] { typeof(string) });//指定要获取的方法名称,和参数类型                 overrideMethodStrint.Invoke(oUser, new object[] { "餐餐" });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型             }                                                   }     } }  

C#高级特性(反射)

4、泛型方法

  • 指定要获取的方法名称,和泛型参数类型
  • 创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection;//第一步引用命名空间 namespace Reflection {     class Program     {         static void Main(string[] args)         {             {                 Console.WriteLine("***********************获取类*****************************");                 //第二步,动态加载类库,写要获取类库的绝对路径                 Assembly assembly= Assembly.LoadFile(@"C:Users炸天张缺缺DesktopReflectionReflection.ModelbinDebugReflection.Model.dll");                 //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀                 Type type = assembly.GetType("Reflection.Model.UsersInfo");                 Console.WriteLine(type.Name);                 Console.WriteLine("***********************获取属性*****************************");                 //遍历类型的属性集合                 foreach (var item in type.GetProperties())                 {                     Console.WriteLine(item.Name+"   "+item.PropertyType);                 }                  Console.WriteLine("***********************普通方法*****************************");                 object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象                 MethodInfo commonMethod = type.GetMethod("CommonMethod");//指定要获取的方法名称                 commonMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空                  Console.WriteLine("***********************带参数的方法*****************************");                 MethodInfo parameterMethod = type.GetMethod("ParameterMethod");//指定要获取的方法名称                 parameterMethod.Invoke(oUser, new object[] { "餐餐"});//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型                  Console.WriteLine("***********************重载方法int参数*****************************");                 MethodInfo overrideMethodInt = type.GetMethod("OverrideMethod",new Type[] { typeof(int)});//指定要获取的方法名称,和参数类型                 overrideMethodInt.Invoke(oUser, new object[] { 18 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型                  Console.WriteLine("***********************重载方法string参数*****************************");                 MethodInfo overrideMethodStrint = type.GetMethod("OverrideMethod", new Type[] { typeof(string) });//指定要获取的方法名称,和参数类型                 overrideMethodStrint.Invoke(oUser, new object[] { "餐餐" });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型                  Console.WriteLine("***********************泛型方法*****************************");                 MethodInfo genericityMethod = type.GetMethod("GenericityMethod").MakeGenericMethod(new Type[] {typeof(int)});//指定要获取的方法名称,和泛型参数类型                 genericityMethod.Invoke(oUser, new object[] { 123 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型             }                                                   }     } }  

C#高级特性(反射)

5、私有方法

  • 指定要获取的方法名称,指明是父类的私有方法
  • 创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Reflection;//第一步引用命名空间 namespace Reflection {     class Program     {         static void Main(string[] args)         {             {                 Console.WriteLine("***********************获取类*****************************");                 //第二步,动态加载类库,写要获取类库的绝对路径                 Assembly assembly= Assembly.LoadFile(@"C:Users炸天张缺缺DesktopReflectionReflection.ModelbinDebugReflection.Model.dll");                 //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀                 Type type = assembly.GetType("Reflection.Model.UsersInfo");                 Console.WriteLine(type.Name);                 Console.WriteLine("***********************获取属性*****************************");                 //遍历类型的属性集合                 foreach (var item in type.GetProperties())                 {                     Console.WriteLine(item.Name+"   "+item.PropertyType);                 }                  Console.WriteLine("***********************普通方法*****************************");                 object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象                 MethodInfo commonMethod = type.GetMethod("CommonMethod");//指定要获取的方法名称                 commonMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空                  Console.WriteLine("***********************带参数的方法*****************************");                 MethodInfo parameterMethod = type.GetMethod("ParameterMethod");//指定要获取的方法名称                 parameterMethod.Invoke(oUser, new object[] { "餐餐"});//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型                  Console.WriteLine("***********************重载方法int参数*****************************");                 MethodInfo overrideMethodInt = type.GetMethod("OverrideMethod",new Type[] { typeof(int)});//指定要获取的方法名称,和参数类型                 overrideMethodInt.Invoke(oUser, new object[] { 18 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型                  Console.WriteLine("***********************重载方法string参数*****************************");                 MethodInfo overrideMethodStrint = type.GetMethod("OverrideMethod", new Type[] { typeof(string) });//指定要获取的方法名称,和参数类型                 overrideMethodStrint.Invoke(oUser, new object[] { "餐餐" });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型                  Console.WriteLine("***********************泛型方法*****************************");                 MethodInfo genericityMethod = type.GetMethod("GenericityMethod").MakeGenericMethod(new Type[] {typeof(int)});//指定要获取的方法名称,和泛型参数类型                 genericityMethod.Invoke(oUser, new object[] { 123 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型                  Console.WriteLine("***********************泛型方法*****************************");                 MethodInfo privateMethod = type.GetMethod("PrivateMethod",BindingFlags.Instance|BindingFlags.NonPublic);//指定要获取的方法名称,指明是父类的私有方法                 privateMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型             }                                                   }     } }  

C#高级特性(反射)

6、静态方法

 Console.WriteLine("***********************静态方法*****************************");                 MethodInfo staticMethod = type.GetMethod("StaticMethod");//指定要获取的方法名称                 staticMethod.Invoke(null, null);//不需要实例化,所以第一个可以不写,为空 

C#高级特性(反射)

四、小扩展,反射书写ORM(请原谅我没有注释)

接口

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;  namespace NineMonthExam.IDAL {     public interface IEFHelpers<T> where T:class     {         bool Add(T t);         bool Remove(int id);         bool Edit(T t);         List<T> GetAll();     } }  

dbhelp类

using NineMonthExam.IDAL; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Configuration; using System.Data.SqlClient; using NineMonthExam.Model;  namespace NineMonthExam.DAL {     public  class DBHelpers<T> : IEFHelpers<T> where T : BaseModel     {         private static  Type type;         private static string typeName;         private static string nameStr;         private static string noIdNameStr;         private static string sql = "";         private static StringBuilder addStr = new StringBuilder();         private static StringBuilder getStr = new StringBuilder();         private static StringBuilder removeStr = new StringBuilder();         private static StringBuilder modify = new StringBuilder();         private static StringBuilder modifyStr = new StringBuilder();         private static string conStr=ConfigurationManager.ConnectionStrings["conStr"].ConnectionString;         static DBHelpers()             {             type = typeof(T);             typeName = type.Name;             nameStr =string.Join(",", type.GetProperties().Select(m=>m.Name));             noIdNameStr = string.Join(",", type.GetProperties().Where(m=>!m.Name.Equals("Id")).Select(m => m.Name));             addStr.Append($@"insert into {typeName} ({noIdNameStr}) values ({string.Join(",", type.GetProperties().Where(m => !m.Name.Equals("Id")).Select(m =>$"@{m.Name}"))})");             getStr.Append($@"select {nameStr} from {typeName}");             removeStr.Append($@"delete from {typeName}");             modify.Append($@"update {typeName} set");             foreach (var item in type.GetProperties().Where(m => !m.Name.Equals("Id")).Select(m => m.Name))             {                 modify.Append($@" {item}=@{item},");             }             string qian = modify.ToString();             qian = qian.Remove(qian.LastIndexOf(','));             modifyStr.Append(qian);             }                  public  bool Add(T t)         {             SqlParameter[] parameters = type.GetProperties().Where(m => !m.Name.Equals("Id")).Select(m => new SqlParameter($"@{m.Name}", m.GetValue(t) ?? DBNull.Value)).ToArray();             sql = addStr.ToString();             using (SqlConnection conn = new SqlConnection(conStr))             {                 conn.Open();                 SqlCommand com = new SqlCommand(sql,conn);                 com.Parameters.AddRange(parameters);                 return com.ExecuteNonQuery() > 0;             }         }          public  bool Edit(T t)         {             SqlParameter[] parameters = type.GetProperties().Select(m => new SqlParameter($"@{m.Name}", m.GetValue(t)??DBNull.Value)).ToArray();             string edit=$" where Id = @{type.GetProperty("Id").Name}";             sql = modifyStr.ToString()+ edit;             using (SqlConnection conn = new SqlConnection(conStr))             {                 conn.Open();                 SqlCommand com = new SqlCommand(sql, conn);                 com.Parameters.AddRange(parameters);                 return com.ExecuteNonQuery() > 0;             }         }         private T GetT(SqlDataReader sdr)         {             T obj = Activator.CreateInstance(type) as T;             foreach (var item in type.GetProperties())             {                 if (sdr[item.Name].GetType() != typeof(DBNull))                 {                     item.SetValue(obj, sdr[item.Name]);                 }                 else                 {                     item.SetValue(obj, null);                  }             }             return obj;         }         public  List<T> GetAll()         {             sql = getStr.ToString();             using (SqlConnection conn = new SqlConnection(conStr))             {                 conn.Open();                 SqlCommand com = new SqlCommand(sql, conn);                 SqlDataReader reader =com.ExecuteReader();                 List<T> list = new List<T>();                 while (reader.Read())                 {                     list.Add(GetT(reader));                 }                 return list;             }         }          public  bool Remove(int id)         {              string del=$" where Id = {id}";             sql = removeStr.ToString()+del;             using (SqlConnection conn = new SqlConnection(conStr))             {                 conn.Open();                 SqlCommand com = new SqlCommand(sql, conn);                 return com.ExecuteNonQuery() > 0;             }         }     } }  

五、结束语:所有的成功都离不开努力,不要用不公平掩饰你不努力的样子

所有的成功都离不开努力,不要用不公平掩饰你不努力的样子