• 通过反射调用類的方法,屬性,字段,索引器(2種方法)


    Type是System.Reflection功能的根 (Root),也是存取Metadata的主要方法.
    使用Type的成員可以取得相關資訊,例如建構函式(Constructor),方法,字段,屬性和類別的事件,以及模組和部署類別的組件(Assembly).

    3種取得Type的方法:
    1.靜態方法
    Type.GetType()
    2.運算符
    typeof()
    3.實例的方法GetType
    Employee e=new Employee();
    e.GetType()

    在一般情況下我們调用的方法並传递给它们的参数,某些情况下可能希望根据用户操作动态调用方法.
    通过Reflection命名空间
    方法1是使用Type对象上的InvokeMember方法
    方法2是使用MethodInfo对象上的Invoke方法

    example:
    先定義類Employee
    其中有靜態屬性Data
    實例屬性Name,ID
    2個索引器

        /// <summary>
        
    /// 自定義類
        
    /// </summary>
        public class Employee
        {
            
    string name;
            
    int id;

            ArrayList list; 

            
    static int data;
            
            
    //instance .ctor()
            public Employee( int id, String name ) 
            {
                
    this.name = name;
                
    this.id = id;

                list
    =new ArrayList();

                
    this.list.Add( "001" );
                
    this.list.Add( "002" );
            }

            
    //static .ctor()
            static Employee()
            {
                data
    =119;
            }

            
    public override string ToString ()
            {
                
    return "Id="+ id.ToString() + ", Name=" + name;
            }

            
    //instance Method "add"
            public string add( string key1,string key2 )
            {
                
    string result=key1+key2;
                
    return result;
            }
            
            
    //static Method "add"
            public static string add( string key1,string key2,string key3 )
            {
                
    return key1+key2+key3;
            }

            
    public string Name 
            {
                
    get 
                { 
                    
    return  name; 
                }
                
    set 
                { 
                    name 
    = value; 
                }
            }

            
    public int ID 
            {
                
    get 
                { 
                    
    return  id; 
                }
                
    set 
                { 
                    id 
    = value; 
                }
            }

            
    public static int Data
            {
                
    get
                {
                    
    return data;
                }
                
    set
                {
                    data
    =value;
                }
            }

            
    /// <summary>
            
    /// by index
            
    /// </summary>
            public string this [ int index ]
            {
                
    get
                {
                    
    return list[index].ToString();
                }
                
    set
                {
                    list[index]
    =value;
                }
            }

            
    /// <summary>
            
    /// by value
            
    /// </summary>
            public string this [ string values]
            {
                
    set
                {
                    
    this[list.IndexOf(values)]=value;
                }
            }

        }

    動態調用:

    定義變量

                string result=String.Empty;
                
    int i;

                Type t
    =typeof( Employee );
                
                Employee e
    =new Employee(1000,"no 1000");



    方法1是使用Type对象上的InvokeMember方法:
    先動態調用類Employee的實例方法ToString
    InvokeMember方法的第一個參數是要調用的方法名稱
    第2個參數是位枚舉,代表搜尋的方式
    第四個參數是要調用的對象,要是靜態的就用null
    第五個參數是要傳送給ToString的數值,由於ToString方法是無參方法,這裡我們送一個空數組new object[]{}

    1             //call instance Method "ToString"
    2             result=(typeof(Employee).InvokeMember("ToString",
    3                                                     BindingFlags.InvokeMethod,    
    4                                                     null,
    5                                                     e,    
    6                                                     new object[]{})).ToString();
    7             Console.WriteLine("instance Method 'ToString' result={0}", result );
    8 


    再動態調用類Employee的實例方法add,靜態方法add
    注意InvokeMember方法的第5個參數代表的是要傳送給add方法的數值
    第8個參數代表的是add方法的參數名稱

                //call instance Method "add"
                result=typeof(Employee).InvokeMember("add",
                                                    BindingFlags.InvokeMethod,
                                                    
    null,
                                                    e,
                                                    
    new object[]{"o1","o2"},
                                                    
    null,
                                                    
    null,
                                                    
    new string[]{"key1","key2"}).ToString();
                Console.WriteLine(
    "instance Method 'add' result={0}", result );

                
    //call static Method "add"
                result=typeof(Employee).InvokeMember("add",
                                                    BindingFlags.InvokeMethod 
    | BindingFlags.Static | BindingFlags.Public ,
                                                    
    null,
                                                    
    null,
                                                    
    new object[]{"o1","o2","o3"},
                                                    
    null,
                                                    
    null,
                                                    
    new string[]{"key1","key2","key3"}).ToString();
                Console.WriteLine(
    "static Method 'add' result={0}",result );
                Console.WriteLine();


    再修改靜態屬性Data,把它從119修改為911

     1             //call static Property
     2             i=(int)typeof(Employee).InvokeMember("Data",
     3                                                 BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static,
     4                                                 null,
     5                                                 null,
     6                                                 new object[]{});
     7             Console.WriteLine("static Property 'Data'={0}", i );
     8 
     9             //update static Property
    10             typeof(Employee).InvokeMember("data",
    11                                             BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
    12                                             null,
    13                                             null,
    14                                             new object[]{911});
    15             Console.WriteLine("update static Property ");
    16 
    17             //call static Property
    18             i=(int)typeof(Employee).InvokeMember("Data",
    19                                                 BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static,
    20                                                 null,
    21                                                 null,
    22                                                 new object[]{});
    23             Console.WriteLine( "again call static Property 'Data'={0}",i );
    24             Console.WriteLine();
    25 


    再修改實例屬性Name,把它從no 1000修改為w

     1             //read instance Property
     2             result=typeof(Employee).InvokeMember("Name",
     3                                                 BindingFlags.GetProperty ,
     4                                                 null,    
     5                                                 e,    
     6                                                 new object[]{}).ToString();
     7             Console.WriteLine( "instance Property 'Name'={0}", result );
     8 
     9             //update instance property
    10             typeof(Employee).InvokeMember("name"
    11                                             BindingFlags.SetField | BindingFlags.NonPublic  | BindingFlags.Instance    ,
    12                                             null,
    13                                             e,
    14                                             new object[]{"w"});
    15             Console.WriteLine("update instance property ");
    16             
    17             //again call read instance Property
    18             result=typeof(Employee).InvokeMember("Name",
    19                                                     BindingFlags.GetProperty ,
    20                                                     null,    
    21                                                     e,
    22                                                     new object[]{}).ToString();
    23             Console.WriteLine( "again call instance Property 'Name'={0}", result );
    24             Console.WriteLine();
    25 


    再修改索引器,把索引器的第2個(index[1])內容修改為222
    注意修改索引器的InvokeMember方法,第5個參數的數組new object[]{"002","222"}
    将要设置元素的索引值放在对象数组的第一个元素中,将要设置的值作为第二个元素

     1             //call index[1] 
     2             result=typeof(Employee).InvokeMember("Item",
     3                                                     BindingFlags.GetProperty,
     4                                                     null,
     5                                                     e,
     6                                                     new object[]{1}).ToString() ;
     7             Console.WriteLine("index[1]={0}", result);
     8 
     9             //update  index[1] 
    10             typeof(Employee).InvokeMember("Item",
    11                                             BindingFlags.SetProperty,
    12                                             null,    
    13                                             e,
    14                                             new object[]{"002","222"});
    15             Console.WriteLine("update  index[1] ");
    16 
    17             //again call index[1]
    18             result=typeof(Employee).InvokeMember("Item",
    19                                                 BindingFlags.GetProperty,
    20                                                 null,
    21                                                 e,
    22                                                 new object[]{1}).ToString() ;
    23 
    24             Console.WriteLine("again call index[1]={0}", result);
    25             Console.WriteLine();
    26 


    調用構造器
    InvokeMember方法的第1個參數為空字符""

    1             //call instance .ctor()
    2             Employee employee=(Employee)typeof(Employee).InvokeMember("",
    3                                                                         BindingFlags.CreateInstance,
    4                                                                         null,
    5                                                                         null,
    6                                                                         new object[]{123,"no 123"});
    7             
    8             Console.WriteLine(employee.ToString());
    9             Console.WriteLine();



    方法2是使用MethodInfo对象上的Invoke方法:

     1             //call Instance Method 'add'
     2             MethodInfo methodInfo1=t.GetMethod("add",BindingFlags.Instance | BindingFlags.Public);
     3             //Instance Method,first parameter is one Instance 
     4             result=methodInfo1.Invoke(new Employee(1,"") ,new object[]{"key1","key2"}).ToString();
     5             Console.WriteLine("call Instance Method 'add' result={0}",result);
     6 
     7             //call Static Method 'add'
     8             MethodInfo methodInfo2=t.GetMethod("add",BindingFlags.Static | BindingFlags.Public);
     9             //Static Method,first parameter is Null 
    10             result=methodInfo2.Invoke(null,    new object[]{"key1","key2","key3"}).ToString();
    11             Console.WriteLine("call Static Method 'add' result={0}",result);
    12 



    結果圖片:

  • 相关阅读:
    PAT1001
    关于yahoo.com.cn邮箱导入Gmail邮箱验证异常的机制解析及解决办法
    浙大机试感受
    PAT1002
    mysql修改密码后无法登陆问题
    Windows 不能在 本地计算机 启动 OracleDBConsoleorcl
    Deprecated: Function ereg_replace() is deprecated
    PHP中静态方法(static)与非静态方法的使用及区别
    微信小程序开发,weui报“渲染层错误”的解决办法
    Android系统下载管理DownloadManager功能介绍及使用示例
  • 原文地址:https://www.cnblogs.com/ghfsusan/p/1406955.html
Copyright © 2020-2023  润新知