精华内容
下载资源
问答
  • java反射 概念

    2017-07-14 13:04:00
    一、什么是反射机制 简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息。二、哪里用到反射机制 有些时候,我们用过一些知识,...

    一、什么是反射机制 
            简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字, 
        那么就可以通过反射机制来获得类的所有信息。 
    二、哪里用到反射机制 
            有些时候,我们用过一些知识,但是并不知道它的专业术语是什么,在刚刚学jdbc时用过一行代码, 
        Class.forName("com.mysql.jdbc.Driver.class").newInstance();但是那时候只知道那行代码是生成 
        驱动对象实例,并不知道它的具体含义。听了反射机制这节课后,才知道,原来这就是反射,现在很多开 
        框架都用到反射机制,hibernate、struts都是用反射机制实现的。 
    三、反射机制的优点与缺点 
            为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念, 
        静态编译:在编译时确定类型,绑定对象,即通过。 
        动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多 
        态的应用,有以降低类之间的藕合性。 
        一句话,反射机制的优点就是可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中 
        它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编 
        译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如 
        这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能 
        的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功 
        能。 
           它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它 
        满足我们的要求。这类操作总是慢于只直接执行相同的操作。 
    四、利用反射机制能获得什么信息 
             一句话,类中有什么信息,它就可以获得什么信息,不过前提是得知道类的名字,要不就没有后文了 
        首先得根据传入的类的全名来创建Class对象。 
        Class c=Class.forName("className");注明:className必须为全名,也就是得包含包名,比如,cn.netjava.pojo.UserInfo; 
        Object obj=c.newInstance();//创建对象的实例 
        OK,有了对象就什么都好办了,想要什么信息就有什么信息了。   
        获得构造函数的方法 
        Constructor getConstructor(Class[] params)//根据指定参数获得public构造器

        Constructor[] getConstructors()//获得public的所有构造器

        Constructor getDeclaredConstructor(Class[] params)//根据指定参数获得public和非public的构造器

        Constructor[] getDeclaredConstructors()//获得public的所有构造器 
        获得类方法的方法 
        Method getMethod(String name, Class[] params),根据方法名,参数类型获得方法

        Method[] getMethods()//获得所有的public方法

        Method getDeclaredMethod(String name, Class[] params)//根据方法名和参数类型,获得public和非public的方法

        Method[] getDeclaredMethods()//获得所以的public和非public方法 
        获得类中属性的方法 
        Field getField(String name)//根据变量名得到相应的public变量

        Field[] getFields()//获得类中所以public的方法

        Field getDeclaredField(String name)//根据方法名获得public和非public变量

        Field[] getDeclaredFields()//获得类中所有的public和非public方法 
        常用的就这些,知道这些,其他的都好办…… 
    五、用反射机制能干什么事 
            刚开始在使用jdbc时侯,在编写访问数据库时写到想吐,有八个表,每个表都有增删改查中操作 
        那时候还不知道有反射机制这个概念,所以就对不同的表创建不同的dao类,这样不仅开发速率地,而且代码 
        冗余的厉害,最要命的是看着差不多的,然后直接复制修改,由于容易犯各种低级的错误(大小写啊,多一 
        个或少一个字母啊……),一个错误就可以让你找半天。 
            有了java反射机制,什么都好办了,只需要写一个dao类,四个方法,增删改查,传入不同的对象,就OK啦, 
        无需为每一个表都创建dao类,反射机制会自动帮我们完成剩下的事情,这就是它的好处。说白了,反射机制就是专门 
        帮我们做那些重复的有规则的事情,所以现在很多的自动生成代码的软件就是运用反射机制来完成的,只要你按照规则 
        输入相关的参数,所以低级的程序员慢慢的就被抹杀了,为什么?因为代码都不用写了,随便一个人都会开发,还要程 
        序员干什么啊?所以我们只有一条出路,那就是努力努力再努力,成为高级程序员,专门开发傻瓜软件,让其他程序员  到 一边凉快去,呵呵~ 
    六、用反射机制实现对数据库数据的增、查例子 
        基本原理;保存数据时,把需要保存的对象的属性值全部取出来再拼凑sql语句 
                     查询时,将查询到的数据全部包装成一个java对象。 
        游戏规则:俗话说的好,无规矩不成方圆,特别是程序来说,它只能做有规则的事情,没有规则的它干不了,好,那就 
                  先定规则 
                  1)数据库的每一个表对象一个pojo类,表中的每一个字段对应pojo类的中的一个属性。 
                     并且pojo类的名字和表的名字相同,属性名和字段名相同,大小写没有关系,因为数据库一般不区分大小写  
                  2)为pojo类中的每一个属性添加标准的set和get方法。 
        有了游戏规则,那么开始游戏吧。

    1、首先数据库的有一个表,假设数据库名称为:blogsystem,里面的一个表名userinfo。如图:

    2、创建对应的pojo类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    package cn.netjava.pojo;
     
    public class  UserInfo {
    private int  id ;
    private String name;
    private String pwd;
    private int  age;
     
    @Override
    public String toString() {
         return  "UserInfo [id="  +  id  +  ", name="  +  name +  ", pwd="  +  pwd +  ", age="
                 +  age +  "]" ;
    }
    public int  getId() {
         return  id ;
    }
    public void setId( int  id ) {
         this. id  =  id ;
    }
    public String getName() {
         return  name;
    }
    public void setName(String name) {
         this.name =  name;
    }
    public String getPwd() {
         return  pwd;
    }
    public void setPwd(String pwd) {
         this.pwd =  pwd;
    }
    public int  getAge() {
         return  age;
    }
    public void setAge( int  age) {
         this.age =  age;
    }
     
    }
    2、编写获得数据库连接的工厂类:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    package cn.netjava.factory;
     
    import  java.sql.Connection;
    import  java.sql.DriverManager;
     
    public class  Connect2DBFactory {
         public static Connection getDBConnection() {
             Connection conn =  null;
             try  {
                 Class.forName( "com.mysql.jdbc.Driver" );
                 String url =  "jdbc:mysql://localhost:3306/blogsystem" ;
                 String user =  "root" ;
                 String password =  "netjava" ;
                 conn =  DriverManager.getConnection(url, user, password);
             } catch (Exception e) {
                 e.printStackTrace();
             }
     
             return  conn;
         }
    }

     

    3、好戏开始啦,编写操作数据库的dao类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    package cn.netjava.session;
     
    import  java.lang.reflect.Field;
    import  java.lang.reflect.Method;
    import  java.sql.Connection;
    import  java.sql.PreparedStatement;
    import  java.sql.ResultSet;
    import  java.sql.SQLException;
    import  java.sql.Statement;
    import  java.util.ArrayList;
    import  java.util. List ;
     
    import  cn.netjava.factory.Connect2DBFactory;
    import  cn.netjava.pojo.UserInfo;
     
    public class  NetJavaSession {
         / * *
          *  解析出保存对象的sql语句
          *
          *  @param object
          *             :需要保存的对象
          *  @ return :保存对象的sql语句
          * /
         public static String getSaveObjectSql( Object  object ) {
             / /  定义一个sql字符串
             String sql =  "insert into " ;
             / /  得到对象的类
             Class c =  object .getClass();
             / /  得到对象中所有的方法
             Method[] methods =  c.getMethods();
             / /  得到对象中所有的属性
             Field[] fields =  c.getFields();
             / /  得到对象类的名字
             String cName =  c.getName();
             / /  从类的名字中解析出表名
             String tableName =  cName.substring(cName.lastIndexOf( "." ) +  1 ,
                     cName.length());
             sql + =  tableName +  "(" ;
             List <String> mList =  new ArrayList<String>();
             List  vList =  new ArrayList();
             for  (Method method : methods) {
                 String mName =  method.getName();
                 if  (mName.startsWith( "get" ) && !mName.startsWith( "getClass" )) {
                     String fieldName =  mName.substring( 3 , mName.length());
                     mList.add(fieldName);
                     System.out.println( "字段名字----->"  +  fieldName);
                     try  {
                         Object  value =  method.invoke( object , null);
                         System.out.println( "执行方法返回的值:"  +  value);
                         if  (value instanceof String) {
                             vList.add( "\""  +  value +  "\"" );
                             System.out.println( "字段值------>"  +  value);
                         } else  {
                             vList.add(value);
                         }
                     } catch (Exception e) {
                         e.printStackTrace();
                     }
                 }
             }
             for  ( int  i =  0 ; i < mList.size(); i + + ) {
                 if  (i < mList.size() -  1 ) {
                     sql + =  mList.get(i) +  "," ;
                 } else  {
                     sql + =  mList.get(i) +  ") values(" ;
                 }
             }
             for  ( int  i =  0 ; i < vList.size(); i + + ) {
                 if  (i < vList.size() -  1 ) {
                     sql + =  vList.get(i) +  "," ;
                 } else  {
                     sql + =  vList.get(i) +  ")" ;
                 }
             }
     
             return  sql;
         }
     
         public static List  getDatasFromDB(String tableName, int  Id ) {
     
             return  null;
     
         }
     
         / * *
          *  将对象保存到数据库中
          *
          *  @param object
          *             :需要保存的对象
          *  @ return :方法执行的结果; 1 :表示成功, 0 :表示失败
          * /
         public int  saveObject( Object  object ) {
             Connection con =  Connect2DBFactory.getDBConnection();
             String sql =  getSaveObjectSql( object );
             try  {
                 / /  Statement statement = (Statement) con.createStatement();
                 PreparedStatement psmt =  con.prepareStatement(sql);
                 psmt.executeUpdate();
                 return  1 ;
             } catch (SQLException e) {
                 e.printStackTrace();
                 return  0 ;
             }
         }
     
         / * *
          *  从数据库中取得对象
          *
          *  @param arg0
          *             :对象所属的类
          *  @param id
          *             :对象的 id
          *  @ return :需要查找的对象
          * /
         public Object  getObject(String className, int  Id ) {
             / /  得到表名字
             String tableName =  className.substring(className.lastIndexOf( "." ) +  1 ,
                     className.length());
             / /  根据类名来创建Class对象
             Class c =  null;
             try  {
                 c =  Class.forName(className);
     
             } catch (ClassNotFoundException e1) {
     
                 e1.printStackTrace();
             }
             / /  拼凑查询sql语句
             String sql =  "select * from "  +  tableName +  " where Id="  +  Id ;
             System.out.println( "查找sql语句:"  +  sql);
             / /  获得数据库链接
             Connection con =  Connect2DBFactory.getDBConnection();
             / /  创建类的实例
             Object  obj =  null;
             try  {
     
                 Statement stm =  con.createStatement();
                 / /  得到执行查寻语句返回的结果集
                 ResultSet set  =  stm.executeQuery(sql);
                 / /  得到对象的方法数组
                 Method[] methods =  c.getMethods();
                 / /  遍历结果集
                 while  ( set . next ()) {
                     obj =  c.newInstance();
                     / /  遍历对象的方法
                     for  (Method method : methods) {
                         String methodName =  method.getName();
                         / /  如果对象的方法以 set 开头
                         if  (methodName.startsWith( "set" )) {
                             / /  根据方法名字得到数据表格中字段的名字
                             String columnName =  methodName.substring( 3 ,
                                     methodName.length());
                             / /  得到方法的参数类型
                             Class[] parmts =  method.getParameterTypes();
                             if  (parmts[ 0 ] = =  String. class ) {
                                 / /  如果参数为String类型,则从结果集中按照列名取得对应的值,并且执行改 set 方法
                                 method.invoke(obj, set .getString(columnName));
                             }
                             if  (parmts[ 0 ] = =  int . class ) {
                                 method.invoke(obj, set .getInt(columnName));
                             }
                         }
     
                     }
                 }
     
             } catch (Exception e) {
                 e.printStackTrace();
             }
             return  obj;
         }
    }

     

    4、开始测试效果怎么样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package cn.netjava.tester;
     
    import  cn.netjava.pojo.UserInfo;
    import  cn.netjava.session.NetJavaSession;
     
    public class  Tester {
         public static void main(String args[]) {
             / / 获得NetJavaSession对象
             NetJavaSession session =  new NetJavaSession();
             / / 创建一个UserInfo对象
             UserInfo user =  new UserInfo();
             / / 设置对象的属性
             user.setId( 6988 );
             user.setAge( 44 );
             user.setPwd( "pwd" );
             user.setName( "champion" );
             / / 将对象保存到数据库中
             String sql =  session.getSaveObjectSql(user);
             System.out.println( "保存对象的sql语句:"  +  sql);
             / / 查找对象
             UserInfo userInfo =  (UserInfo) session.getObject(
                     "cn.netjava.pojo.UserInfo" , 6988 );
             System.out.println( "获取到的信息:"  +  userInfo);
     
         }
    }

     

    5、打印出来的结果:

    七、总节一下

          总的来说,java反射机制是一个很好用的东西,用它可以解决很多死的东西,因为反射机制的灵活行很大,有了他,我们就不要花太多的时间来写操做数据库的代码了,而是方法更多的时间在项目的逻辑功能上,这个可以很大的减少开发时间,而且代码的可读性好。先在的很多开源框架都是才用的反射机制,它只要配置文件,然后按规则来调用他的方法就可以了。

     
    分类:  java

    转载于:https://www.cnblogs.com/KingIceMou/p/7169625.html

    展开全文
  • 反射机制的概念

    2020-12-25 14:44:10
    另外一个场景,想要在运行期获得某个类的Class信息如它的属性、构造方法、一般方法后再考虑是否创建它的对象,这种情况就需要用到反射! 1)java文件在编译后会变成.Class文件,这就像是个镜面,本身是.Java,在镜...

    目录

     

    前言

    反射机制的作用

    IOC容器的技术剖析

    反射与工厂模式实现IOC

    下面用反射机制实现工厂模式:

    总结:



     

    前言

    考虑一个场景,在程序运行时,一个对象想要检查自己所拥有的成员变量属性,该如何操作?另外一个场景,想要在运行期获得某个类的Class信息如它的属性、构造方法、一般方法后再考虑是否创建它的对象,这种情况就需要用到反射!

    1)java文件在编译后会变成.Class文件,这就像是个镜面,本身是.Java,在镜中是.Class,他们其实是一样的;同理,看到镜子的反射是.Class,就能通过反编译,了解到.Java文件的本来面目。

    2)对于反射,官方给出的概念:反射是Java语言的一个特性,它允许在程序运行时(注意不是编译的时候)来进行自我的检查并且对内部的成员进行操作。例如它允许一个Java类获取它所有的成员变量和方法并且显示出来。

    3)反射主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。在Java中,只要给定类的名字,那么就可以通过反射机制来获取类的所有信息

    4)反射是Java中的一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时进行装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!类中有什么信息,利用反射机制就能可以获得什么信息,不过前提是得知类的名字。

     

    反射机制的作用

    1)在运行时判断任意一个对象所属的类

    2)在运行时获取类的对象

    3)在运行时访问java对象的属性,方法,构造方法等

    首先需要搞清楚为什么要反射机制?这就涉及到了动态与静态的概念。

    静态编译:在编译时确定类型,绑定对象,即通过。

    动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了Java的灵活性,体现了多态的应用,降低类之间的耦合性。

     

    IOC容器的技术剖析

    1)IOC中最基本的技术就是“反射(Reflection)”编程,通俗来讲就是根据给出的类名(字符串方式)来动态的生成对象,这种编程方式可以让对象在生成时才被决定到底是哪一种对象。只是在spring中要生产 的对象都在配置文件中给出定义,目的就是提高灵活性和可维护性;

    2)目前C#、Java和PHP5等语言均已支持反射,其中PHP5的技术书籍中,有时候也被译成“映射”。有关反射的概念和用法,大家应该都很清楚,反射的应用是很广泛的,很多的成熟框架,比如像Java中的Hibernate、Spring框架,。NET中的NHibernate、Spring.NET框架都是把“反射”作为最基本的技术手段;

    3)反射技术其实很早就出现了,但是一直被忽略,没有被进一步的利用,当时的反射编程方式相对于正常的对象生成方式要慢至少10倍,现在的反射技术经过改良优化,已经非常成熟,反射方式生成对象和通常对象生成方式,速度已经相差不大了,大约是1-2倍的差距。

    4)我们可以把IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看做是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言提供的反射机制,根据配置文件给出的类名生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,改变为有配置问价来定义,也就是把工厂和对象生成的这两者独立分割开来,目的就是提高灵活性和可维护性。

     

    反射与工厂模式实现IOC

    Spring 中的IoC 的实现原理就是工厂模式加反射机制。我们首先看一下不用反射机

    制时的工厂模式:

    interface fruit {
    
    public abstract void eat();
    
    }
    
    
    
    class Apple implements fruit{
    
    public void eat(){
    
    System.out.println("Apple");
    
    }
    
    }
    
    
    
    class Orange implements fruit{
    
    public void eat(){
    
    System.out.println("Orange");
    
    }
    
    }

     

    //也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了

    class Factory{
    
    public static fruit getInstance(String fruitName){
    
    fruit f=null;
    
    if("Apple".equals(fruitName)){
    
    f=new Apple();
    
    } if("Orange".equals(fruitName)){
    
    f=new Orange();
    
    }
    
    return f;
    
    }
    
    }
    
    
    
    class hello{
    
    public static void main(String[] a){
    
    fruit f=Factory.getInstance("Orange");
    
    f.eat();
    
    }
    
    }

     

    上面写法的缺点是当我们再添加一个子类的时候,就需要修改工厂类了。如果我们添加太多的子类的时候,改动就会很多。

     

    下面用反射机制实现工厂模式:

    interface fruit {
    
    public abstract void eat();
    
    }
    
    
    
    class Apple implements fruit{
    
    public void eat(){
    
    System.out.println("Apple");
    
    }
    
    }
    
    
    
    class Orange implements fruit{
    
    public void eat(){
    
    System.out.println("Orange");
    
    }
    
    }
    
    class Factory{
    
    public static fruit getInstance(String ClassName){
    
    fruit f=null;
    
    try{
    
    f=(fruit)Class.forName(ClassName).newInstance();
    
    }catch (Exception e) {
    
    e.printStackTrace();
    
    }
    
    return f;
    
    }
    
    }
    
    
    
    class hello{
    
    public static void main(String[] a){
    
    fruit f=Factory.getInstance("Reflect.Apple");
    
    if(f!=null){
    
    f.eat();
    
    }
    
    }
    
    }

    总结:

    现在就算我们添加任意多个子类的时候,工厂类都不需要修改。使用反射机制实现的工

    厂模式可以通过反射取得接口的实例,但是需要传入完整的包和类名。而且用户也无法知道

    一个接口有多少个可以使用的子类,所以我们通过属性文件的形式配置所需要的子类。

     

    展开全文
  • 反射实例及概念

    2017-12-29 20:40:00
    net的应用程序由几个部分:‘程序集’,‘模块’,‘类型’组成,而反射提供一种编程方式,让程序员可以在程序运行期获得这几个组成部分的相关信息, 例如:  assembly类可以获得正在运行的装配件信息,也可以...

    反射:

      Relection,中文翻译为反射,这是。NET 中获取运行时类型信息的方式。

      。net的应用程序由几个部分:‘程序集’,‘模块’,‘类型’组成,而反射提供一种编程方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,

    例如:

      assembly类可以获得正在运行的装配件信息,也可以动态加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。

      Type类可以获得对象的 类型信息,此信息包含对象的所有要素:方法、 构造器、 属性等等,通过Type类可以得到这些要素的信息,并且调用之。

      MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。还有FIeldInfo(字段)、EventInfo(事件)。。。

      这些类都包含在System.Relection命名空间下。

     

      程序用来处理数据的,文泵和特性都是数据,而我们程序本身(类的定义和BLC中的类)这些也是数据。

      有关程序及其类型的数据被称为元数据(metadata),它们是保存在程序的程序集中。

      反射:

        程序在运行时,可一个查看其它程序集或其本身的元数据,一个运行的程序查看本身的元数据或者其它程序集的元数据的行为。

        反射提供了描述程序集,模块和类型的对象(Type类型)。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段

        和属性,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口、枚举)的成员和成员的信息。有了反射,即可对每一个类型了如指掌。另外我还可以                直接创建对象,即使这个对象的类型在编译时还不知道。下面是使用静态方法GetType(从Object基类派生的所有类型都继承该方法)获取变量类型的简单反射实例:

      int i= 42;

      System.Type type = i.GeType();

      System.Console.WriteLine(type);

     

    特性的概念和用法

      特性(Attribute)用于在运行时传递程序中的各种元素(比如类、 方法、 结构、 枚举、 组件、等)的行为信息的声明性标签。您可以通过使用特性向程序添加性信息。一个声明性标签是通过放置在它所应用的元素前面括号(【】)来描述的。

      特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。.Net提供了两种类型的特性:预定义特性和自定义特性。

     

      规定特性:【attribute(positoinal_parameters,name_parameter = vale,.........)】

            element

        特性的名称和值是放在括号内规定的,放置在它所应用的元素之前。positional_parameters 规定必须的信息,name_parameter规定可选的信息。

      

      预定义特性(Attribute)

        》.Net框架提供了三种预定义的特性:

        》AttributeUsage : 规定了特性可应用到的项目类型。

          【AttributeUsage(

              validon,    规定特性可被放置的语言元素,是枚举器AttributeTargets的值得组合。默认值是AttributeTargets.All.

              AllowMultiple = allowmultiple, (可选的)  为该特性的AllowMultiple属性(property)提供一个布尔值。如果为true,则该属性是多用的;

                                                             如果为false,则该属性是单用的。

              Inherited = inherited (可选的) 为该特性提供一个bool值,如果为true,则该特性可被派生类继承。默认是false(不被继承)

          )】

        》Conditional  : 这个预定义特性标记了一个条件方法,其执行依赖于它项的预处理标示符。它会引起方法调用的条件编译,取决于指定的值,比如Debug或Trace。例如:                                          当调试时显示变量的值。

          【Conditional(

              conditionalSymbol                     Conditional("DEBUG")

          )】

     

        》Obsolete:标记了不应被使用的程序实体。他可以让您通知编译器丢弃某个特定的目标元素。例如:当一个新方法被用在一个类中,但是您仍然想要保持类中的旧方法,您可以通过显示一个使用新方法,而不是旧方法的消息,来把它标记为obsolete(过时的)。

          

           【Obsolete(

              meesage

            )】

            [Obsolete(

              message,  是一个字符串,描述项目为什么过时的原因以及该替代使用什么。

              iserror  是一个布尔值,如果为true,编译器应把该项目的使用当做一个错误,默认值是false(编译器生成一个警告)

            )]

       创建自定义特性(Attribute)

          Net框架允许创建自定义特性,用于存储声明性的信息,且可在运行时被检索。该信息根据设计标准和应用程序需要,可与任何目标元素相关。

          创建并使用自定义 特性包含四个步骤:

            》声明自定义特性

            》构建自定义特性

            》在目标程序元素上应用定义特性

            》通过反射访问特性

          最后一个步骤包含一个简单的程序来读取元数据以便查找各种符号。元数据是用于描述其他数据的数据和信息。该程序应使用反射来在运行时访问特性。

             //一个自定义特性 BugFix 被赋给类及其成员

              

     [AttributeUsage(AttributeTargets.Class|
                AttributeTargets.Constructor |
                AttributeTargets.Field|
                AttributeTargets.Method|
                AttributeTargets.Property,
                AllowMultiple = true
                )]
                public class DeBugInfo: System.AttributeTargets

      我们在源代码中将特性应用于程序结构:

        编译器获取源代码并且从特性产生元数据,然后把元数据放到程序集中;

        消费者程序可以获取特性的元数据以及程序中其他组件的元数据。注意,编译器同时生产和消费特性。

        关于特性的命名规范,特性名使用Pascal命名法(首字母大写),并且Attribute后缀结尾,当目标应用特性时,我们可以不使用后缀。例如SerializableAttribute和                                 MyAttribuetAttribute这两个特性,我们把他们应用到结构是可以使用Serializable和MyAttribute.

    应用特性:

        目的:告诉编译器把程序结构的某组元数据嵌入程序集。我们可以通过吧特性应用到结构来实现。

           在结构前放置特性片段来应用特性:

           特性片段被方括号包围,特性片段包括特姓名和特性的参数列表;

           应用了特性的结构成为特性装饰。

        其他预定义特性:

            特性         意义

          CLSCompliant     声明可以公开的成员应该被编译器检查是否符合CLS。兼容的程序可以被任何。NET兼容的语言使用

          Serializable    声明结构可以被序列化

          NonSerialized   声明结构不可以被序列化

          DLL mport         声明是非托管代码实现的

          WebMethod    声明方法应该被作为XML Web服务的一部分暴露

          AttributeUsage   声明性能应用到什么类型的程序结构。将这个特性应用到特性声明上

          Assembly                         全局特性

     

    转载于:https://www.cnblogs.com/Jason-365/p/8138179.html

    展开全文
  • net反射详解

    2018-07-25 20:42:56
    MSDN:反射(C# 编程指南) -----------------原文如下-------- 1、 什么是反射 2、 命名空间与装配件的关系 3、 运行期得到类型信息有什么用 4、 如何使用反射获取类型 5、 如何根据类型来动态创建对象 6、 如何...

    本人理解:

    装配件:Assembly(程序集)

    晚绑定:后期绑定

    MSDN:反射(C# 编程指南)

    -----------------原文如下--------

    1、 什么是反射
    2、 命名空间与装配件的关系
    3、 运行期得到类型信息有什么用
    4、 如何使用反射获取类型
    5、 如何根据类型来动态创建对象
    6、 如何获取方法以及动态调用方法
    7、 动态创建委托

    1、什么是反射
            Reflection,中文翻译为反射。
            这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如:

            Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。
    Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。
    MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。
    诸如此类,还有FieldInfo、EventInfo等等,这些类都包含在System.Reflection命名空间下。

    2、命名空间与装配件的关系
            很多人对这个概念可能还是很不清晰,对于合格的.Net程序员,有必要对这点进行澄清。
            命名空间类似与Java的包,但又不完全等同,因为Java的包必须按照目录结构来放置,命名空间则不需要。

            装配件是.Net应用程序执行的最小单位,编译出来的.dll、.exe都是装配件。

            装配件和命名空间的关系不是一一对应,也不互相包含,一个装配件里面可以有多个命名空间,一个命名空间也可以在多个装配件中存在,这样说可能有点模糊,举个例子:
    装配件A:

    1. namespace  N1
    2. {
    3.       public  class  AC1  {…}
    4.       public  class  AC2  {…}
    5. }
    6. namespace  N2
    7. {
    8.       public  class  AC3  {…}
    9.       public  class  AC4{…}
    10. }

    复制代码

    装配件B:

    1. namespace  N1
    2. {
    3.       public  class  BC1  {…}
    4.       public  class  BC2  {…}
    5. }
    6. namespace  N2
    7. {
    8.       public  class  BC3  {…}
    9.       public  class  BC4{…}
    10. }

    复制代码

    这两个装配件中都有N1和N2两个命名空间,而且各声明了两个类,这样是完全可以的,然后我们在一个应用程序中引用装配件A,那么在这个应用程序中,我们能看到N1下面的类为AC1和AC2,N2下面的类为AC3和AC4。
            接着我们去掉对A的引用,加上对B的引用,那么我们在这个应用程序下能看到的N1下面的类变成了BC1和BC2,N2下面也一样。
            如果我们同时引用这两个装配件,那么N1下面我们就能看到四个类:AC1、AC2、BC1和BC2。

            到这里,我们可以清楚一个概念了,命名空间只是说明一个类型是那个族的,比如有人是汉族、有人是回族;而装配件表明一个类型住在哪里,比如有人住在北京、有人住在上海;那么北京有汉族人,也有回族人,上海有汉族人,也有回族人,这是不矛盾的。

            上面我们说了,装配件是一个类型居住的地方,那么在一个程序中要使用一个类,就必须告诉编译器这个类住在哪儿,编译器才能找到它,也就是说必须引用该装配件。
            那么如果在编写程序的时候,也许不确定这个类在哪里,仅仅只是知道它的名称,就不能使用了吗?答案是可以,这就是反射了,就是在程序运行的时候提供该类型的地址,而去找到它。
    有兴趣的话,接着往下看吧。

    3、运行期得到类型信息有什么用
            有人也许疑问,既然在开发时就能够写好代码,干嘛还放到运行期去做,不光繁琐,而且效率也受影响。
    这就是个见仁见智的问题了,就跟早绑定和晚绑定一样,应用到不同的场合。有的人反对晚绑定,理由是损耗效率,但是很多人在享受虚函数带来的好处的时侯还没有意识到他已经用上了晚绑定。这个问题说开去,不是三言两语能讲清楚的,所以就点到为止了。
            我的看法是,晚绑定能够带来很多设计上的便利,合适的使用能够大大提高程序的复用性和灵活性,但是任何东西都有两面性,使用的时侯,需要再三衡量。

    接着说,运行期得到类型信息到底有什么用呢?
    还是举个例子来说明,很多软件开发者喜欢在自己的软件中留下一些接口,其他人可以编写一些插件来扩充软件的功能,比如我有一个媒体播放器,我希望以后可以很方便的扩展识别的格式,那么我声明一个接口:

    1. public  interface  IMediaFormat
    2. {
    3. string  Extension  {get;}
    4. Decoder  GetDecoder();
    5. }

    复制代码

    这个接口中包含一个Extension属性,这个属性返回支持的扩展名,另一个方法返回一个解码器的对象(这里我假设了一个Decoder的类,这个类提供把文件流解码的功能,扩展插件可以派生之),通过解码器对象我就可以解释文件流。
    那么我规定所有的解码插件都必须派生一个解码器,并且实现这个接口,在GetDecoder方法中返回解码器对象,并且将其类型的名称配置到我的配置文件里面。
    这样的话,我就不需要在开发播放器的时侯知道将来扩展的格式的类型,只需要从配置文件中获取现在所有解码器的类型名称,而动态的创建媒体格式的对象,将其转换为IMediaFormat接口来使用。

    这就是一个反射的典型应用。


    4、如何使用反射获取类型
            首先我们来看如何获得类型信息。
            获得类型信息有两种方法,一种是得到实例对象
            这个时侯我仅仅是得到这个实例对象,得到的方式也许是一个object的引用,也许是一个接口的引用,但是我并不知道它的确切类型,我需要了解,那么就可以通过调用System.Object上声明的方法GetType来获取实例对象的类型对象,比如在某个方法内,我需要判断传递进来的参数是否实现了某个接口,如果实现了,则调用该接口的一个方法:

    1. public  void  Process(  object  processObj  )
    2. {
    3. Type  t  =  processsObj.GetType();
    4. if(  t.GetInterface(“ITest”)  !=null  )
    5.                     …
    6. }

    复制代码

    另外一种获取类型的方法是通过Type.GetType以及Assembly.GetType方法,如:
                  Type  t  =  Type.GetType(“System.String”);
            需要注意的是,前面我们讲到了命名空间和装配件的关系,要查找一个类,必须指定它所在的装配件,或者在已经获得的Assembly实例上面调用GetType。
            本装配件中类型可以只写类型名称,另一个例外是mscorlib.dll,这个装配件中声明的类型也可以省略装配件名称(.Net装配件编译的时候,默认都引用了mscorlib.dll,除非在编译的时候明确指定不引用它),比如:
              System.String是在mscorlib.dll中声明的,上面的Type  t  =  Type.GetType(“System.String”)是正确的
              System.Data.DataTable是在System.Data.dll中声明的,那么:
    Type.GetType(“System.Data.DataTable”)就只能得到空引用。
              必须:
    Type  t  =  Type.GetType("System.Data.DataTable,System.Data,Version=1.0.3300.0,  Culture=neutral,  PublicKeyToken=b77a5c561934e089");
              这样才可以,大家可以看下面这个帖子:
                    http://expert.csdn.net/Expert/to ... 2.xml?temp=.1919977
              qqchen的回答很精彩


    5、如何根据类型来动态创建对象
            System.Activator提供了方法来根据类型动态创建对象,比如创建一个DataTable:

    1. Type  t  =  Type.GetType("System.Data.DataTable,System.Data,Version=1.0.3300.0,  Culture=neutral,  PublicKeyToken=b77a5c561934e089");
    2.  
    3. DataTable  table  =  (DataTable)Activator.CreateInstance(t);

    复制代码

    例二:根据有参数的构造器创建对象

    1. namespace  TestSpace  
    2. {
    3.   public  class  TestClass
    4.       {
    5.       private  string  _value;
    6.       public  TestClass(string  value)  
    7.     {
    8.       _value=value;
    9.       }
    10.   }
    11. }
    12. Type  t  =  Type.GetType(“TestSpace.TestClass”);
    13. Object[]  constructParms  =  new  object[]  {“hello”};  //构造器参数
    14. TestClass  obj  =  (TestClass)Activator.CreateInstance(t,constructParms);

    复制代码

    把参数按照顺序放入一个Object数组中即可


    6、如何获取方法以及动态调用方法

    1. namespace  TestSpace
    2. {
    3.       public  class  TestClass  {
    4.           private  string  _value;
    5.           public  TestClass()  {
    6.           }
    7.           public  TestClass(string  value)  {
    8.                 _value  =  value;
    9.           }
    10.  
    11.           public  string  GetValue(  string  prefix  )  {
    12.           if(  _value==null  )
    13.           return  "NULL";
    14.           else
    15.             return  prefix+"  :  "+_value;
    16.             }
    17.  
    18.             public  string  Value  {
    19. set  {
    20. _value=value;
    21. }
    22. get  {
    23. if(  _value==null  )
    24. return  "NULL";
    25. else
    26. return  _value;
    27. }
    28.             }
    29.       }
    30. }

    复制代码

    上面是一个简单的类,包含一个有参数的构造器,一个GetValue的方法,一个Value属性,我们可以通过方法的名称来得到方法并且调用之,如:

    1. //获取类型信息
    2. Type  t  =  Type.GetType("TestSpace.TestClass");
    3. //构造器的参数
    4. object[]  constuctParms  =  new  object[]{"timmy"};
    5. //根据类型创建对象
    6. object  dObj  =  Activator.CreateInstance(t,constuctParms);
    7. //获取方法的信息
    8. MethodInfo  method  =  t.GetMethod("GetValue");
    9. //调用方法的一些标志位,这里的含义是Public并且是实例方法,这也是默认的值
    10. BindingFlags  flag  =  BindingFlags.Public  |  BindingFlags.Instance;
    11. //GetValue方法的参数
    12. object[]  parameters  =  new  object[]{"Hello"};
    13. //调用方法,用一个object接收返回值
    14. object  returnValue  =  method.Invoke(dObj,flag,Type.DefaultBinder,parameters,null);

    复制代码

    属性与方法的调用大同小异,大家也可以参考MSDN

    7、动态创建委托
            委托是C#中实现事件的基础,有时候不可避免的要动态的创建委托,实际上委托也是一种类型:System.Delegate,所有的委托都是从这个类派生的
            System.Delegate提供了一些静态方法来动态创建一个委托,比如一个委托:

    1. namespace  TestSpace  {
    2.       delegate  string  TestDelegate(string  value);
    3.       public  class  TestClass  {
    4. public  TestClass()  {
    5.                   }
    6.                   public  void  GetValue(string  value)  {
    7.                           return  value;
    8.                   }
    9.         }
    10. }

    复制代码

    使用示例:

    1. TestClass  obj  =  new  TestClass();
    2.  
    3. //获取类型,实际上这里也可以直接用typeof来获取类型
    4. Type  t  =  Type.GetType(“TestSpace.TestClass”);
    5. //创建代理,传入类型、创建代理的对象以及方法名称
    6. TestDelegate  method  =  (TestDelegate)Delegate.CreateDelegate(t,obj,”GetValue”);
    7.  
    8. String  returnValue  =  method(“hello”);

    复制代码

    ---------------------------------------------------------------------------------

    另外一篇关于反射的文章

    ---------------原文如下------------------

    反射的定义:审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。
              System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码   

    System.Reflection.Assembly 
    System.Reflection.MemberInfo
    System.Reflection.EventInfo
    System.Reflection.FieldInfo
    System.Reflection.MethodBase
    System.Reflection.ConstructorInfo
    System.Reflection.MethodInfo
    System.Reflection.PropertyInfo
    System.Type
    以下是上面几个类的使用方法:
    (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。 
    (2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。 
    (3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或 GetConstructor方法来调用特定的构造函数。 
    (4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。 
    (5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。 
    (6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。 
    (7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。 
    (8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
    反射的层次模型:

    (注:层次间都是一对多的关系)

     

    反射的作用:
    1、可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型
    2、应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射。
    3、反射主要应用与类库,这些类库需要知道一个类型的定义,以便提供更多的功能。

    应用要点:
    1、现实应用程序中很少有应用程序需要使用反射类型
    2、使用反射动态绑定需要牺牲性能
    3、有些元数据信息是不能通过反射获取的
    4、某些反射类型是专门为那些clr 开发编译器的开发使用的,所以你要意识到不是所有的反射类型都是适合每个人的。

     

    反射appDomain 的程序集:

    当你需要反射AppDomain 中包含的所有程序集,示例如下:
    static void Main
    {
           //通过GetAssemblies 调用appDomain的所有程序集
           foreach (Assembly assem in Appdomain.currentDomain.GetAssemblies())
          {
           //反射当前程序集的信息
                reflector.ReflectOnAssembly(assem)
          }
    }

    说明:调用AppDomain 对象的GetAssemblies 方法 将返回一个由System.Reflection.Assembly元素组成的数组。


    反射单个程序集:

    上面的方法讲的是反射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 方法


    利用反射获取类型信息:

    前面讲完了关于程序集的反射,下面在讲一下反射层次模型中的第三个层次,类型反射
    一个简单的利用反射获取类型信息的例子:

    using system;
    using sytem.reflection;
    class reflecting 
    {
           static void Main(string[]args)
           {
                 reflecting reflect=new reflecting();//定义一个新的自身类
                 //调用一个reflecting.exe程序集

                 assembly myAssembly =assembly.loadfrom(“reflecting.exe”)
                 reflect.getreflectioninfo(myAssembly);//获取反射信息
           }

           //定义一个获取反射内容的方法
           void getreflectioninfo(assembly myassembly)
           {
                 type[] typearr=myassemby.Gettypes();//获取类型
                 foreach (type type in typearr)//针对每个类型获取详细信息
                {
                       //获取类型的结构信息
                      constructorinfo[] myconstructors=type.GetConstructors;

                     //获取类型的字段信息
                     fieldinfo[] myfields=type.GetFiedls()

                     //获取方法信息
                     MethodInfo   myMethodInfo=type.GetMethods();

                     //获取属性信息
                     propertyInfo[] myproperties=type.GetProperties

                     //获取事件信息
                     EventInfo[] Myevents=type.GetEvents;
               }
          }
    }
    其它几种获取type对象的方法:
    1、System.type   参数为字符串类型,该字符串必须指定类型的完整名称(包括其命名空间)
    2、System.type 提供了两个实例方法:GetNestedType,GetNestedTypes
    3、Syetem.Reflection.Assembly 类型提供的实例方法是:GetType,GetTypes,GetExporedTypes
    4、System.Reflection.Moudle 提供了这些实例方法:GetType,GetTypes,FindTypes


    设置反射类型的成员:

    反射类型的成员就是反射层次模型中最下面的一层数据。我们可以通过type对象的GetMembers 方法取得一个类型的成员。如果我们使用的是不带参数的GetMembers,它只返回该类型的公共定义的静态变量和实例成员,我们也可以通过使用带参数的 GetMembers通过参数设置来返回指定的类型成员。具体参数参考msdn 中system.reflection.bindingflags 枚举类型的详细说明。

    例如:
    //设置需要返回的类型的成员内容
    bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public;
    foreach (MemberInfo mi int t.getmembers(bf))
    {
           writeline(mi.membertype)    //输出指定的类型成员
    }


    通过反射创建类型的实例:

    通过反射可以获取程序集的类型,我们就可以根据获得的程序集类型来创建该类型新的实例,这也是前面提到的在运行时创建对象实现晚绑定的功能
    我们可以通过下面的几个方法实现:
    1、System.Activator 的CreateInstance方法。该方法返回新对象的引用。具体使用方法参见msdn
    2、System.Activator 的createInstanceFrom 与上一个方法类似,不过需要指定类型及其程序集
    3、System.Appdomain 的方法:createInstance,CreateInstanceAndUnwrap,CreateInstranceFrom和CreateInstraceFromAndUnwrap
    4、System.type的InvokeMember实例方法:这个方法返回一个与传入参数相符的构造函数,并构造该类型。
    5、System.reflection.constructinfo 的Invoke实例方法

    反射类型的接口:

    如果你想要获得一个类型继承的所有接口集合,可以调用Type的FindInterfaces GetInterface或者GetInterfaces。所有这些方法只能返回该类型直接继承的接口,他们不会返回从一个接口继承下来的接口。要想返回接口的基础接口必须再次调用上述方法。


    反射的性能:

    使用反射来调用类型或者触发方法,或者访问一个字段或者属性时clr 需要做更多的工作:校验参数,检查权限等等,所以速度是非常慢的。所以尽量不要使用反射进行编程,对于打算编写一个动态构造类型(晚绑定)的应用程序,可以采取以下的几种方式进行代替:
    1、通过类的继承关系。让该类型从一个编译时可知的基础类型派生出来,在运行时生成该类型的一个实例,将对其的引用放到其基础类型的一个变量中,然后调用该基础类型的虚方法。
    2、通过接口实现。在运行时,构建该类型的一个实例,将对其的引用放到其接口类型的一个变量中,然后调用该接口定义的虚方法。
    3、通过委托实现。让该类型实现一个方法,其名称和原型都与一个在编译时就已知的委托相符。在运行时先构造该类型的实例,然后在用该方法的对象及名称构造出该委托的实例,接着通过委托调用你想要的方法。这个方法相对与前面两个方法所作的工作要多一些,效率更低一些。

     

    个人操作方案:

    源DLL类:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web.UI;
    using System.Collections;


    namespace cn.SwordYang
    {

        public class TextClass:System.Web.UI.Page
        {

    public static void RunJs(Page _page, string Source)
            {
                _page.ClientScript.RegisterStartupScript(_page.GetType(), "", "<script type=\"text/javascript\">" + Source + ";</script>");

            }

    }

    }

    //调用代码

    System.Reflection.Assembly ass = Assembly.LoadFrom(Server.MapPath("bin/swordyang.dll")); //加载DLL
                System.Type t = ass.GetType("cn.SwordYang.TextClass");//获得类型
                object o = System.Activator.CreateInstance(t);//创建实例

                System.Reflection.MethodInfo mi = t.GetMethod("RunJs");//获得方法


                mi.Invoke(o, new object[] { this.Page,"alert('测试反射机制')"});//调用方法

    反射机制对应设计模式中的策略模式。

    展开全文
  • net 反射机制

    2010-05-20 09:45:00
    4月7日.net 反射机制提纲: 1、 什么是反射 2、 命名空间与装配件的关系 3、 运行期得到类型信息有什么用 4、 如何使用反射获取类型 5、 如何根据类型来动态创建对象 6、 如何获取方法以及动态调用方法 7、 ...
  • 今天突然想通了,默认你先知道反射是这么用的,但是不明白反射到底用在什么场景,既然知道了对象,为啥不用对象直接开new,还要通过反射绕这么一大圈? 例子1 反射可以用来开发程序插件一类的,比如浏览器支持插件...
  • 概述反射  通过反射可以提供类型信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象。   反射机制允许程序在执行过程中动态地添加各种功能。   运行时类型标识  运行时类型标识...
  • Java的动态性支持学习一 - 反射机制 概念概述 Java的动态性支持学习二 - 反射机制 属性、方法、对象的操作 Java的动态性支持学习三 - 反射机制 取消属性、方法、构造器的访问限制 Java的动态性支持学习四 - 反射...
  • Net反射(转载)--对比Java反射 1、什么是反射 Reflection,中文翻译为反射。 这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成...
  • 1. Proxy代理 // 供应商(原始对象) let obj = { ... name:'net', _r: "123" } // 创建代理商,传入obj数据 let monitor = new Proxy(obj,{ get(target,key){ // 拦截对象属性的读取 tar...
  • Net反射在项目中的应用 反射的概念和基本原理msdn很详细,这个文章主要说说反射在我的项目中的应用 反射用的比较多一个概念是程序集,也可以认为就是dll类库,程序集是所有类型的集合,它还有一个重要的东西就是元...
  • 原文链接:http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html ... 一、什么是反射机制   简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名
  • 反射

    2019-07-04 14:00:28
    反射的含义 反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。 在运行状态中(在运行的过程中生成对象),对于任意一个类,都能够获取到这...
  • 反射基础

    2017-08-25 18:09:49
    反射概念 其实就是动态加载一个指定的类,并获取该类中的所有的内容。而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员。简单说:反射技术可以对一个类进行解剖。 反射的...
  • Java反射

    2020-06-18 14:46:42
    Java反射1 概述1.1 概念1.2 反射的作用1.3 反射的优缺点2 反射机制(Class 和 java.lang.reflect.*)2.1 概述2.2 Class3 使用反射3.1 获得Class的三种方式3.2 使用Class类的对象来生成目标类的实例3.3 统一形式调用...
  • 反射机制

    2017-11-28 17:27:05
    概念反射机制是在运行状态中,对任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 ...
  • Net中的反射使用入门

    2019-08-08 03:22:38
    Net中的反射使用入门 [转载] MSDN: ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpcondiscoveringtypeinformationatruntime.htm 提纲: 1、什么是反射 2、命名空间与装配件的关系 3、...
  • java 反射

    2018-04-16 18:32:56
    java反射概念反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,希望读者能理解,也就是说,类,类的成员,我们在运行的时候还可以动态地去操作他们.(特别注意运行时)Java反射机制可以让我们在编译期...
  • BGP路由反射器RR

    千次阅读 多人点赞 2020-06-23 13:46:35
    EBGP 对等体之间是不存在 BGP 路由反射器的概念的。 对于大型网络来说,使用路由反射器可以大大减少 IBGP 对等体关系的数量。路由反射器的使用,会明显减少配置工作量,人为出错的可能性也会大大降低。
  • java反射

    2015-10-16 23:58:25
    Java反射机制 一、什么是反射机制   简单的来说,反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,   那么就可以通过反射机制来获得类的所有信息。  二、哪里用到反射机制...
  • Java反射技术

    2018-09-16 21:09:32
    Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;...这一概念的提出很快引发了计算机科学领域关于应用反射性的研...
  • NET Framework 中的反射

    2012-12-01 11:28:10
    1、什么是反射   Reflection,中文翻译为反射。 这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分: ‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,...
  • 这次讲反射的原因,是因为上午答了一个帖子,是关于反射的,发现里面很多人对反射、类型、装配件这些概念都还不了解,甚至有错误的了解,我的正确答案居然只有qqchen才认为是正确的,看来是有必要普及一下这方面的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,312
精华内容 3,324
关键字:

net反射概念