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;
                }
            }
        }
    }
    
    

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

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

    我自是年少,韶华倾负。
  • 相关阅读:
    poj 2485 Highways 最小生成树
    hdu 3415 Max Sum of MaxKsubsequence
    poj 3026 Borg Maze
    poj 2823 Sliding Window 单调队列
    poj 1258 AgriNet
    hdu 1045 Fire Net (二分图匹配)
    poj 1789 Truck History MST(最小生成树)
    fafu 1181 割点
    减肥瘦身健康秘方
    人生的问题
  • 原文地址:https://www.cnblogs.com/ZhangQueque/p/14124825.html
Copyright © 2011-2022 走看看