zoukankan      html  css  js  c++  java
  • 反射基础

    反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型

    (包括类、结构、委托、接口和枚举等)的成员和成员的信息。

    其实有些人会问, 像我们平常引用DLL可以直接用, 为什么要用反射?反射还是对性能有影响的,

    尽管可以通过优化反射的行为缩小之间性能的差距,可能这个时候对于性能要求毫秒级的需求, 那就要适当的取舍是否用反射。

    (尽管对于大部分定制软件开发来说, 软件都是一次开发, 然后二次维护, 很少大的需求面会更改)。

    反射最大的好处就是, 插件化, 动态可配置, 扩展性强。当面临需求的变更亦或新增模块的情况,不用去改动源代码。

    1.利用Assembly去加载DLL程序集

    利用微软现有的结局方案可以实现动态加载Dll程序集, 在System.Reflection命名空间下的Assemly。

    1.新建一个控制台应用程序

    2.新建一个类库ClassLibrary, 新建两个模型 一个Student类 , 一个School类

    public class Student
        {
            public string name { get; set; }
    
            public string sex = "";
    
            public void Hay()
            {
                Console.WriteLine("你们好");
            }
    
            public void Hay(string name)
            {
                Console.WriteLine(name + "你好");
            }
    
    
            public void GoodBye<T>(T name)
            {
                Console.WriteLine(name + "再见");
            }
    
            private void GoodBye()
            {
                Console.WriteLine("再见");
            }
    
            public static void StaticMethod()
            {
                Console.WriteLine("私有方法...");
            }
        }
     public class School
        {
        }

    //利用Assembly.Load方法读取外部的DLL程序集 【默认加载根目录下面DLL】

     //反射加载外部DLL
                Assembly ass = Assembly.Load("ClassLibrary"); //默认加载根目录下面DLL

    //获取程序的Modules

    复制代码
    //获取所有模块
                foreach (var item in ass.GetModules())
                {
                    Console.WriteLine(item.FullyQualifiedName);
                }
    复制代码

    //获取属性, 方法, 字段

    复制代码
     foreach (var item in ass.GetTypes()) //
                {
                    Console.WriteLine(item.FullName); //获取DLL中所有的命名空间
    
                    foreach (var sub in item.GetProperties()) //公开属性
                    {
                        Console.WriteLine(item.Name + "公开属性:" + sub.Name);
                    }
                    foreach (var sub in item.GetMethods()) //公开方法
                    {
                        Console.WriteLine(item.Name + "公开方法:" + sub.Name);
                    }
                    foreach (var sub in item.GetFields()) //公开字段
                    {
                        Console.WriteLine(item.Name + "公开字段:" + sub.Name);
                    }
                }
    复制代码

    //反射创建实例对象

    复制代码
    foreach (var item in ass.GetTypes())
                {
                    if (item.Name.Contains("Student")) //ClassLibrary.Student
                    {
                        //使用Activator 动态去创建一个实例对象, 调用其中的公开方法
                        Student stu = (Student)Activator.CreateInstance(item);
                        stu.Hay();
                    }
                }
    复制代码

    //反射调用实例方法、静态方法、重载方法、私有方法、泛型方法

    复制代码
      foreach (var item in ass.GetTypes())
                {
                    if (item.Name.Contains("Student"))
                    {
                        //Student实例对象
                        object obj = Activator.CreateInstance(item);
    
                        //实例方法
                        MethodInfo method = item.GetMethod("Hay", new Type[] { });
                        method.Invoke(obj, null);
    
                        //重载方法
                        MethodInfo method1 = item.GetMethod("Hay", new Type[] { typeof(string) }); //带参数Hay
                        method1.Invoke(obj, new object[] { "哥哥" });
    
                        //静态方法
                        MethodInfo method2 = item.GetMethod("StaticMethod");
                        method2.Invoke(null, null);
    
                        //私有方法
                        MethodInfo method3 = item.GetMethod("GoodBye", BindingFlags.Instance | BindingFlags.NonPublic);
                        method3.Invoke(obj, null);
    
                        //泛型方法
                        MethodInfo method4 = item.GetMethod("GoodBye");
                        method4 = method4.MakeGenericMethod(typeof(string)); //重点,为泛型声明指定类型
                        method4.Invoke(obj, new object[] { "泛型," });
    
                    }
                }
    复制代码

    //反射字段属性: GetValue SetValue

    复制代码
    foreach (var item in ass.GetTypes())
                {
                    if (item.Name.Contains("Student"))
                    {
                        object obj = Activator.CreateInstance(item);
    
                        foreach (var sub in item.GetProperties())
                        {
                            sub.SetValue(obj, "Mobike"); //SetValue
                            Console.WriteLine(sub.GetValue(obj)); //GetValue
                        }
                    }
                }
    复制代码

    源文:

    https://www.cnblogs.com/zh7791/p/7905237.html

  • 相关阅读:
    PHP 日期的时区差异
    c++与c输出输入语句时空区别
    数据库中完整性约束的SQL定义几点小解
    字符的一字节8位问题
    C#抽象类
    SQL server 中SUBSTRING()以及CONVERT()的用法
    关于CS模式下,控制一个容器内控件的值问题
    新的公司新的感受
    小生谈字符串的截取函数SubString()仅限csharp语言
    LINQ中怎么使用NEWID()之自我学习与理解
  • 原文地址:https://www.cnblogs.com/shy1766IT/p/11312978.html
Copyright © 2011-2022 走看看