通过反射调用類的方法,屬性,字段,索引器(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 



結果圖片:

posted on 2009-03-09 14:06  冬日阳光  阅读(404)  评论(0编辑  收藏  举报

导航