通过反射调用類的方法,屬性,字段,索引器(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>
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;
}
}
}
動態調用:
定義變量
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[]{}
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方法的參數名稱
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
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
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"}
将要设置元素的索引值放在对象数组的第一个元素中,将要设置的值作为第二个元素
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個參數為空字符""
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方法:
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
結果圖片:
/************************************************/
本博客内容如果是原著都会在标题后加上(原著)字样,未加者多数为转载.
/************************************************/