码迷,mamicode.com
首页 > Windows程序 > 详细

C# 反射Reflection——反射反射程序员的快乐

时间:2019-03-11 23:53:37      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:函数   机器码   高级   jit   动态加载   identity   面向   .sql   open   

一、什么是反射
反射Reflection:System.Reflection,是.Net Framework提供的一个帮助类库,可以读取并使用metadata。
反射是无处不在的,MVC-Asp.Net-ORM-IOC-AOP 几乎所有的框架都离不开反射
如下图是程序执行的过程,高级语言经过编译器编译得到dll/exe文件,这里的文件可以跨平台使用,编译后的文件中其实包括了metadata元数据(数据清单,描述了DLL/exe里面的各种信息)和IL(也是一种面向对象语言,但是不太好阅读)在经过CLR/JIT编译得到可以被计算机所执行的机器码。
技术图片
二、反射的使用
一)反射动态加载程序集
技术图片
            Assembly assembly1 = Assembly.LoadFrom(@"DB.MySql.dll");//当前路径
            Assembly assembly2 = Assembly.LoadFile(@"D:\ruanmou\MyReflection\bin\Debug\DB.MySql.dll");//dll、exe文件完整路径
            Assembly assembly3 = Assembly.Load(@"DB.MySql");//dll、exe名称   dll/exe需要拷贝至程序bin文件夹下
View Code

二)简单工厂生产对应实体

技术图片
        /// <summary>
        /// 简单工厂生产对应实体
        /// </summary>
        /// <returns></returns>
        public static T CreateInstance<T>()
        {
            Assembly assembly = Assembly.Load(ConfigurationManager.AppSettings["DalDllName"]);//加载dll
            Type dalType = assembly.GetType(ConfigurationManager.AppSettings["DalTypeName"]);//获取类型
            return (T)Activator.CreateInstance(dalType);//创建对象
            //var newType = dalType.MakeGenericType(typeof(T));//获取泛型类型
            //return (T)Activator.CreateInstance(newType);创建泛型类型对象
        }
View Code

三)常用方法

技术图片
            Type[] types= assembly.GetTypes();//获取程序集所有类型
            Type type= assembly.GetType("TypeName");//获取指定类型
            MethodInfo[] methods= type.GetMethods();//获取所有方法
            MethodInfo method= type.GetMethod("methodName");//获取指定方法
            PropertyInfo[] propertys= type.GetProperties();//获取所有属性
            PropertyInfo property = type.GetProperty("propertyName");//获取指定属性
            FieldInfo[] fields= type.GetFields();//获取所有字段
            FieldInfo field = type.GetField("fieldName");//获取指定字段
            Attribute attribute = type.GetCustomAttribute(typeof(DisplayNameAttribute));//获取指定特性
View Code

反射调用多参数构造函数,方法

技术图片
    /// <summary>
    /// 反射测试类
    /// </summary>
    public class ReflectionTest
    {
        #region Identity
        /// <summary>
        /// 无参构造函数
        /// </summary>
        public ReflectionTest()
        {
            Console.WriteLine("这里是{0}无参数构造函数", this.GetType());
        }

        /// <summary>
        /// 带参数构造函数
        /// </summary>
        /// <param name="name"></param>
        public ReflectionTest(string name)
        {
            Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
        }

        public ReflectionTest(int id)
        {
            Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
        }
        #endregion

        #region Method
        /// <summary>
        /// 无参方法
        /// </summary>
        public void Show1()
        {
            Console.WriteLine("这里是{0}的Show1", this.GetType());
        }
        /// <summary>
        /// 有参数方法
        /// </summary>
        /// <param name="id"></param>
        public void Show2(int id)
        {

            Console.WriteLine("这里是{0}的Show2", this.GetType());
        }
        /// <summary>
        /// 重载方法之一
        /// </summary>
        /// <param name="id"></param>
        /// <param name="name"></param>
        public void Show3(int id, string name)
        {
            Console.WriteLine("这里是{0}的Show3", this.GetType());
        }
        /// <summary>
        /// 重载方法之二
        /// </summary>
        /// <param name="name"></param>
        /// <param name="id"></param>
        public void Show3(string name, int id)
        {
            Console.WriteLine("这里是{0}的Show3_2", this.GetType());
        }
        /// <summary>
        /// 重载方法之三
        /// </summary>
        /// <param name="id"></param>
        public void Show3(int id)
        {

            Console.WriteLine("这里是{0}的Show3_3", this.GetType());
        }
        /// <summary>
        /// 重载方法之四
        /// </summary>
        /// <param name="name"></param>
        public void Show3(string name)
        {

            Console.WriteLine("这里是{0}的Show3_4", this.GetType());
        }
        /// <summary>
        /// 重载方法之五
        /// </summary>
        public void Show3()
        {

            Console.WriteLine("这里是{0}的Show3_1", this.GetType());
        }
        /// <summary>
        /// 私有方法
        /// </summary>
        /// <param name="name"></param>
        private void Show4(string name)
        {
            Console.WriteLine("这里是{0}的Show4", this.GetType());
        }
        /// <summary>
        /// 静态方法
        /// </summary>
        /// <param name="name"></param>
        public static void Show5(string name)
        {
            Console.WriteLine("这里是{0}的Show5", typeof(ReflectionTest));
        }
        #endregion
    }
View Code
技术图片
                Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
                Type type = assembly.GetType("Ruanmou.DB.SqlServer.ReflectionTest");
                object oTest = Activator.CreateInstance(type);//反射调用无参数构造函数
                object oTest2 = Activator.CreateInstance(type, new object[] { 123 });//反射调用一个int类型参数构造函数
                foreach (var method in type.GetMethods())
                {
                    Console.WriteLine(method.Name);
                    foreach (var parameter in method.GetParameters())//获取方法参数
                    {
                        Console.WriteLine($"{parameter.Name}  {parameter.ParameterType}");
                    }
                }
                {
                    ReflectionTest reflection = new ReflectionTest();
                    reflection.Show1();
                }
                {
                    MethodInfo method = type.GetMethod("Show1");
                    //if()
                    method.Invoke(oTest, null);//oTest调用无参数方法
                }
                {
                    MethodInfo method = type.GetMethod("Show2");
                    method.Invoke(oTest, new object[] { 123 });//oTest调用一个int类型参数方法
                }
                {
                    MethodInfo method = type.GetMethod("Show3", new Type[] { });
                    method.Invoke(oTest, null);//oTest调用无参数重载方法
                }
                {
                    MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int) });
                    method.Invoke(oTest, new object[] { 123 });//oTest调用一个int类型参数重载方法
                }
                
                {
                    MethodInfo method = type.GetMethod("Show5");
                    method.Invoke(oTest, new object[] { "String" });//静态方法实例可以要
                }
                {
                    MethodInfo method = type.GetMethod("Show5");
                    method.Invoke(null, new object[] { "string" });//静态方法实例也可以不要
                }
View Code
技术图片
                    var method = type.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic);
                    method.Invoke(oTest, new object[] { "私有方法" });
反射调用私有方法

反射调用泛型方法、泛型类

技术图片
    public class GenericClass<T, W, X>
    {
        public void Show(T t, W w, X x)
        {
            Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
        }
    }

    public class GenericMethod
    {
        public void Show<T, W, X>(T t, W w, X x)
        {
            Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
        }
    }

    public class GenericDouble<T>
    {
        public void Show<W, X>(T t, W w, X x)
        {
            Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
        }
    }
View Code
技术图片
               {
                    Console.WriteLine("********************GenericMethod********************");
                    Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
                    Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericMethod");
                    object oGeneric = Activator.CreateInstance(type);
                    //foreach (var item in type.GetMethods())
                    //{
                    //    Console.WriteLine(item.Name);
                    //}
                    MethodInfo method = type.GetMethod("Show");
                    var methodNew = method.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
                    object oReturn = methodNew.Invoke(oGeneric, new object[] { 123, "test", DateTime.Now });
                }
                {
                    Console.WriteLine("********************GenericMethod+GenericClass********************");
                    Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
                    Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericDouble`1").MakeGenericType(typeof(int));
                    object oObject = Activator.CreateInstance(type);
                    MethodInfo method = type.GetMethod("Show").MakeGenericMethod(typeof(string), typeof(DateTime));
                    method.Invoke(oObject, new object[] { 345, "teat", DateTime.Now });

                }
View Code

反射破坏单例

技术图片
    /// <summary>
    /// 单例模式:类,能保证在整个进程中只有一个实例
    /// </summary>
    public sealed class Singleton
    {
        private static Singleton _Singleton = null;
        private Singleton()
        {
            Console.WriteLine("Singleton被构造");
        }

        static Singleton()
        {
            _Singleton = new Singleton();
        }

        public static Singleton GetInstance()
        {
            return _Singleton;
        }
    }
View Code
技术图片
                  {

                    Console.WriteLine("********************Singleton********************");
                    Singleton singleton1 = Singleton.GetInstance(); //new Singleton();
                    Singleton singleton2 = Singleton.GetInstance();
                    Singleton singleton3 = Singleton.GetInstance();
                    Singleton singleton4 = Singleton.GetInstance();
                    Singleton singleton5 = Singleton.GetInstance();
                    Console.WriteLine($"{object.ReferenceEquals(singleton1, singleton5)}");

                    //反射破坏单例---就是发射调用私有构造函数
                    Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
                    Type type = assembly.GetType("Ruanmou.DB.SqlServer.Singleton");
                    Singleton singletonA = (Singleton)Activator.CreateInstance(type, true);
                    Singleton singletonB = (Singleton)Activator.CreateInstance(type, true);
                    Singleton singletonC = (Singleton)Activator.CreateInstance(type, true);
                    Singleton singletonD = (Singleton)Activator.CreateInstance(type, true);
                    Console.WriteLine($"{object.ReferenceEquals(singletonA, singletonD)}");
                }
View Code

 

C# 反射Reflection——反射反射程序员的快乐

标签:函数   机器码   高级   jit   动态加载   identity   面向   .sql   open   

原文地址:https://www.cnblogs.com/Dewumu/p/10513996.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!