• 【学习笔记】反射


    下面我们直接通过一个Demo来看下反射的使用

    首先来看下Demo的项目结构,很简单就是一个控制台项目引用了一个类库:

    然后来看下类库里面的类

    using System;
    
    namespace MyLibrary
    {
        /// <summary>
        /// 泛型类
        /// </summary>
        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);
            }
        }
    
        /// <summary>
        /// 泛型方法
        /// </summary>
        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);
            }
        }
    
        /// <summary>
        /// 泛型类泛型方法
        /// </summary>
        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);
            }
        }
    }
    using System;
    
    namespace MyLibrary
    {
        /// <summary>
        /// 实体
        /// </summary>
        public class People
        {
            public People()
            {
                Console.WriteLine("{0}被创建", this.GetType().FullName);
            }
    
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public string Description;
        }
    }
    using System;
    
    namespace MyLibrary
    {
        /// <summary>
        /// 反射测试类
        /// </summary>
        public class ReflectionTest
        {
            #region 构造函数
    
            /// <summary>
            /// 无参构造函数
            /// </summary>
            public ReflectionTest()
            {
                Console.WriteLine("这里是{0}无参数构造函数", this.GetType());
            }
    
            /// <summary>
            /// 带参数构造函数
            /// </summary>
            /// <param name="name"></param>
            public ReflectionTest(string name)
            {
                Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
            }
    
            /// <summary>
            /// 带参数构造函数重载
            /// </summary>
            /// <param name="id"></param>
            public ReflectionTest(int id)
            {
                Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
            }
    
            #endregion 构造函数
    
            #region 方法
    
            /// <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 方法
        }
    }
    using System;
    
    namespace MyLibrary
    {
        /// <summary>
        /// 单例模式:类,能保证在整个进程中只有一个实例
        /// </summary>
        public sealed class Singleton
        {
            private static Singleton _singleton = null;
    
            /// <summary>
            /// 私有构造函数
            /// </summary>
            private Singleton()
            {
                Console.WriteLine("Singleton被构造");
            }
    
            /// <summary>
            /// 静态构造函数
            /// </summary>
            static Singleton()
            {
                _singleton = new Singleton();
            }
    
            /// <summary>
            /// 获取单例
            /// </summary>
            public static Singleton GetInstance()
            {
                return _singleton;
            }
        }
    }

    最后我们重点来看下反射的使用

    using System;
    using System.Reflection;
    
    using MyLibrary;
    
    namespace ConsoleApp1
    {
        /// <summary>
        /// metadata元数据:数据清单,描述了DLL/exe里面的各种信息
        /// 反射可以读取并使用metadata
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            {
                //程序集
                {
                    //动态加载程序集 一个完整dll名称不需要后缀  从exe所在的路径进行查找
                    Assembly assembly = Assembly.Load("MyLibrary");
                    //当前路径,相对路径或者绝对路径
                    assembly = Assembly.LoadFrom("MyLibrary.dll");
                    assembly = Assembly.LoadFrom(@"F:TianYaTestConsoleApp1ConsoleApp1inDebug
    etcoreapp3.1MyLibrary.dll");
                    //完整路径
                    assembly = Assembly.LoadFile(@"F:TianYaTestConsoleApp1ConsoleApp1inDebug
    etcoreapp3.1MyLibrary.dll");
                }
    
                //
                {
                    Assembly assembly = Assembly.Load("MyLibrary");
                    foreach (var type in assembly.GetTypes()) //获取所有类型
                    {
                        bool result = type.IsGenericType; //是否是泛型类
                        Console.WriteLine(type.Name);
                        foreach (var method in type.GetMethods())
                        {
                            Console.WriteLine(method.Name);
                        }
                    }
    
                    Type type1 = assembly.GetType("MyLibrary.ReflectionTest");//获取类型 完整类型名称
                    Type type2 = typeof(ReflectionTest);
                    Type type3 = new ReflectionTest().GetType();
                    foreach (ConstructorInfo ctor in type1.GetConstructors()) //构造函数
                    {
                        Console.WriteLine(ctor.Name);
                        foreach (var parameter in ctor.GetParameters()) //参数
                        {
                            Console.WriteLine(parameter.ParameterType);
                        }
                    }
    
                    //创建对象
                    object oTest1 = Activator.CreateInstance(type1);
                    object oTest2 = Activator.CreateInstance(type1, new object[] { 123 });
                    object oTest3 = Activator.CreateInstance(type1, new object[] { "陌殇" });
                }
    
                //反射破坏单例 => 就是反射调用私有构造函数
                {
                    Assembly assembly = Assembly.Load("MyLibrary");
                    Type type = assembly.GetType("MyLibrary.Singleton");
                    Singleton singletonA = (Singleton)Activator.CreateInstance(type, true);
                    Singleton singletonB = (Singleton)Activator.CreateInstance(type, true);
                }
    
                //泛型类
                {
                    Assembly assembly = Assembly.Load("MyLibrary");
                    Type type = assembly.GetType("MyLibrary.GenericClass`3");
                    //GenericClass<string, int, DateTime> genericClass = new GenericClass<string, int, DateTime>();
                    Type typeMake = type.MakeGenericType(new Type[] { typeof(string), typeof(int), typeof(DateTime) });
                    object oGeneric = Activator.CreateInstance(typeMake);
                }
    
                //方法
                {
                    Assembly assembly = Assembly.Load("MyLibrary");
                    Type type = assembly.GetType("MyLibrary.ReflectionTest");
                    object oTest = Activator.CreateInstance(type);
                    foreach (var method in type.GetMethods())
                    {
                        Console.WriteLine(method.Name);
                        foreach (var parameter in method.GetParameters())
                        {
                            Console.WriteLine($"{parameter.Name}  {parameter.ParameterType}");
                        }
                    }
    
                    {
                        MethodInfo method = type.GetMethod("Show1");
                        method.Invoke(oTest, null);
                    }
                    {
                        MethodInfo method = type.GetMethod("Show2");
                        method.Invoke(oTest, new object[] { 123 });
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { });
                        method.Invoke(oTest, null);
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int) });
                        method.Invoke(oTest, new object[] { 123 });
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(string) });
                        method.Invoke(oTest, new object[] { "一生为你" });
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int), typeof(string) });
                        method.Invoke(oTest, new object[] { 234, "心欲无痕" });
                    }
                    {
                        MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(string), typeof(int) });
                        method.Invoke(oTest, new object[] { "PHS", 345 });
                    }
                    {
                        MethodInfo method = type.GetMethod("Show5");
                        method.Invoke(oTest, new object[] { "张中魁" });//静态方法实例可以要
                    }
                    {
                        MethodInfo method = type.GetMethod("Show5");
                        method.Invoke(null, new object[] { "张中魁" });//静态方法实例也可以不要
                    }
                }
    
                //调用私有方法
                {
                    Assembly assembly = Assembly.Load("MyLibrary");
                    Type type = assembly.GetType("MyLibrary.ReflectionTest");
                    object oTest = Activator.CreateInstance(type);
                    var method = type.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic);
                    method.Invoke(oTest, new object[] { "我是老王" });
                }
    
                //泛型方法
                {
                    Assembly assembly = Assembly.Load("MyLibrary");
                    Type type = assembly.GetType("MyLibrary.GenericMethod");
                    object oGeneric = Activator.CreateInstance(type);
                    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, "董小姐", DateTime.Now });
                }
    
                //泛型类 + 泛型方法
                {
                    Assembly assembly = Assembly.Load("MyLibrary");
                    Type type = assembly.GetType("MyLibrary.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, "感谢有梦", DateTime.Now });
                }
    
                //字段和属性
                {
                    Type type = typeof(People);
                    object oPeople = Activator.CreateInstance(type);
                    //属性
                    foreach (var prop in type.GetProperties()) 
                    {
                        Console.WriteLine($"{type.Name}.{prop.Name}={prop.GetValue(oPeople)}");
                        if (prop.Name.Equals("Id"))
                        {
                            prop.SetValue(oPeople, 234);
                        }
                        else if (prop.Name.Equals("Name"))
                        {
                            prop.SetValue(oPeople, "饿了么");
                        }
                        Console.WriteLine($"{type.Name}.{prop.Name}={prop.GetValue(oPeople)}");
                    }
    
                    //字段
                    foreach (var field in type.GetFields()) 
                    {
                        Console.WriteLine($"{type.Name}.{field.Name}={field.GetValue(oPeople)}");
                        if (field.Name.Equals("Description"))
                        {
                            field.SetValue(oPeople, "并不是外卖,也不是真的饿了");
                        }
                        Console.WriteLine($"{type.Name}.{field.Name}={field.GetValue(oPeople)}");
                    }
                }
    
                Console.ReadKey();
            }
        }
    }

    Demo源码:

    链接:https://pan.baidu.com/s/1pdwBFs6q9bnYGX2Y8RdmCw 
    提取码:bnx1
  • 相关阅读:
    转:matplotlib画图,plt.xx和ax.xx之间有什么差异
    转:Python __call__()方法,可调用对象
    训练集,验证集,测试集,交叉验证
    Visio画图和导出图的时候,去除多余白色背景
    在线jupyter notebook
    dfs序
    codeforces 877b
    codeforce864d
    codeforce868c
    查看本地git查看git公钥,私钥的方式
  • 原文地址:https://www.cnblogs.com/xyh9039/p/12584805.html
Copyright © 2020-2023  润新知