zoukankan      html  css  js  c++  java
  • C#高级特性(反射)

    今天来讲解反射的应用:

    一、反射是什么?

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

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

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

    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.ModelinDebugReflection.Model.dll");
                    //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
                    Type type = assembly.GetType("Reflection.Model.UsersInfo");
                    Console.WriteLine(type.Name);
                    
                }
            }
        }
    }
    
    

    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.ModelinDebugReflection.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.ModelinDebugReflection.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);//创建方法,第一个参数,对象,第二个参数,没有则为空
                }
                
                   
                
            }
        }
    }
    
    

    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.ModelinDebugReflection.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对象数组,写对应的参数类型
                }
                
                   
                
            }
        }
    }
    
    

    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.ModelinDebugReflection.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对象数组,写对应的参数类型
                }
                
                   
                
            }
        }
    }
    
    

    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.ModelinDebugReflection.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对象数组,写对应的参数类型
                }
                
                   
                
            }
        }
    }
    
    

    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.ModelinDebugReflection.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对象数组,写对应的参数类型
                }
                
                   
                
            }
        }
    }
    
    

    6、静态方法

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

    四、小扩展,反射书写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;
                }
            }
        }
    }
    
    

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

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

  • 相关阅读:
    解决chrome浏览器无法得到window.showModalDialog返回值的问题
    Javascript 中 null、NaN和undefined的区别
    Windows Server 2003 asp网页不能访问的常见问题
    关于SQLServer无法对数据库'XXX'执行删除,因为它正用于复制。错误:'3724' 的解决方案
    关于Gridview激发了未处理的事件“RowDeleting”错误的处理
    ASP.NET中实现文件下载功能
    C#中ref和out的作用和区别
    关于Pascal(帕斯卡)以及Camel(驼峰)命名法
    期末作业验收
    SDN第五次上机作业
  • 原文地址:https://www.cnblogs.com/augustuss/p/14515518.html
Copyright © 2011-2022 走看看