• C#高级编程之反射


    反射的定义

    MSDN定义:反射提供描述程序集、模块和类型的对象(Type类型)。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问器字段和属性。 如果代码中使用了特性,可以利用反射来访问它们。

    一共三句话。

    第一句意思是可以利用反射提供的API来获取程序集信息,包括其下的模块、Type类型信息;

    第二句意思通过反射,先拿到这个程序集->Module->Type的类型信息,然后调用实例化的API Activator.CreateInstance(type type)来实例化该类型对象,拿到对象instance后,可以对这个对象数据成员进行赋值,然后注入到现有对象B中;或者是利用API获取这个类型下的属性、方法等信息,对其进行读写、调用操作。

    第三句意思是:如果反射获取到的这个类型有使用Attribute特性,可以进行互操作。

    反射使用

    反射一般使用过程如下:

    装载程序集Assmebly

    上面的方法讲的是反射AppDomain的所有程序集,我们可以显示的调用其中的一个程序集,system.reflecton.assembly 类型提供了下面三种方法:
    1、Load 方法:极力推荐的一种方法,Load 方法带有一个程序集标志并载入它,Load 将引起CLR把策略应用到程序集上,先后在全局程序集缓冲区,应用程序基目录和私有路径下面查找该程序集,如果找不到该程序集系统抛出异常
    2、LoadFrom 方法:传递一个程序集文件的路径名(包括扩展名),CLR会载入您指定的这个程序集,传递的这个参数不能包含任何关于版本号的信息,区域性,和公钥信息,如果在指定路径找不到程序集抛出异常。
    3、LoadWithPartialName:永远不要使用这个方法,因为应用程序不能确定再在载入的程序集的版本。该方法的唯一用途是帮助那些在.Net框架的测试环节使用.net 框架提供的某种行为的客户,这个方法将最终被抛弃不用。

    注意:system.AppDomain 也提供了一种Load 方法,他和Assembly的静态Load 方法不一样,AppDomain的load 方法是一种实例方法,返回的是一个对程序集的引用,Assembly的静态Load 方发将程序集按值封装发回给发出调用的AppDomain.尽量避免使用AppDomain的load 方法。

    获取类型信息

        //定义一个获取反射内容的方法
            static void getreflectioninfo(Assembly myassembly)
            {
                Type[] typearr = myassembly.GetTypes();//获取类型
                foreach (Type type in typearr)//针对每个类型获取详细信息
                {
                    //获取类型的结构信息
                    ConstructorInfo[] myconstructors = type.GetConstructors();
    
                    //获取类型的字段信息
                    FieldInfo[] myfields = type.GetFields();
    
                    //获取方法信息
                    MethodInfo[] myMethodInfo = type.GetMethods();
    
                    //获取属性信息
                    PropertyInfo[] myproperties = type.GetProperties();
    
                    //获取事件信息
                    EventInfo[] Myevents = type.GetEvents();
                }
            }

    调用普通类泛型方法

    泛型方法签名:public void Show<T,W,X>(T t,W,w,X x);

    Assembly assmebly=Assembly.Load("")
    Type type=assembly.GetType("namespace.sqlServerHelper");
    dbHeperInstace =Activator.CreateInstace(type)
    MethodInfo genericMethod=type.GetMethod("show");
    MethodInfo genericMethod1=genericMethod.MakeGenericMethod(new Type[]{typeof(int),typeof(string),typeof(DateTime)};
    genericMethod1.invoke(dbHeperInstace,new object[]{123,"john",DateTime.Now};

    调用泛型类里面泛型方法

    【[此处的Show方法的具体参数的type类型依赖于class上的<T,W,X>]】eg.

    class GenericClass<T,W,X>
    {
    public void Show<T,W,X>(T t,W,w,X x)
    }
    [占位符]
    Type type=assembly.GetType("namespace.sqlServerHelper.GenericClass`3");
    Type type1=type.MakeGenericType(new Type[]{typeof(int),typeof(string),typeof(DateTime)};
    object GenericdbHeperInstace =Activator.CreateInstace(type1);
    MethodInfo genericMethod=type1.GetMethod("show");
    genericMethod.invoke(GenericdbHeperInstace,new object[]{123,"john",DateTime.Now});

    反射设置属性值

    对于属性的操作具体可以参考 https://blog.csdn.net/shuzhongke123/article/details/106091047

    总结

    反射特点:
    动态 减少对象与对象之间的依赖,只需要知道类名,方法名就可以调用,还可以突破特定权限,可以做到普通方式无法做到的。
    性能问题:经过缓存优化之后,是普通的10倍。对于性能损耗,请理性看待。

    参考:https://www.cnblogs.com/wangshenhe/p/3256657.html

  • 相关阅读:
    Java——Java重写和重载
    Java——继承
    Java——Java异常(不完整)
    Java——Stream、File、IO
    前端规范整理
    网站前端优化 -saveForSelf
    PhoneGap与WAP站静态化
    js执行顺序
    前端优化-内容优化-郑钧
    HTTP协议-标签简介
  • 原文地址:https://www.cnblogs.com/shuzhongke/p/14005401.html
Copyright © 2020-2023  润新知