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> publicclassEmployee { stringname; intid;
ArrayListlist;
staticintdata;
//instance.ctor() publicEmployee(intid,Stringname) { this.name=name; this.id=id;
list=newArrayList();
this.list.Add("001"); this.list.Add("002"); }
//static.ctor() staticEmployee() { data=119; }
publicoverridestringToString() { return"Id="+id.ToString()+",Name="+name; }
//instanceMethod"add" publicstringadd(stringkey1,stringkey2) { stringresult=key1+key2; returnresult; }
//staticMethod"add" publicstaticstringadd(stringkey1,stringkey2,stringkey3) { returnkey1+key2+key3; }
publicstringName { get { returnname; } set { name=value; } }
publicintID { get { returnid; } set { id=value; } }
publicstaticintData { get { returndata; } set { data=value; } }
///<summary> ///byindex ///</summary> publicstringthis[intindex] { get { returnlist[index].ToString(); } set { list[index]=value; } }
///<summary> ///byvalue ///</summary> publicstringthis[stringvalues] { set { this[list.IndexOf(values)]=value; } }
}
動態調用:
定義變量
stringresult=String.Empty; inti;
Typet=typeof(Employee);
Employeee=newEmployee(1000,"no1000");
方法1是使用Type对象上的InvokeMember方法: 先動態調用類Employee的實例方法ToString InvokeMember方法的第一個參數是要調用的方法名稱 第2個參數是位枚舉,代表搜尋的方式 第四個參數是要調用的對象,要是靜態的就用null 第五個參數是要傳送給ToString的數值,由於ToString方法是無參方法,這裡我們送一個空數組new object[]{}
1//callinstanceMethod"ToString" 2result=(typeof(Employee).InvokeMember("ToString", 3BindingFlags.InvokeMethod, 4null, 5e, 6newobject[]{})).ToString(); 7Console.WriteLine("instanceMethod'ToString'result={0}",result); 8
再動態調用類Employee的實例方法add,靜態方法add 注意InvokeMember方法的第5個參數代表的是要傳送給add方法的數值 第8個參數代表的是add方法的參數名稱
//callinstanceMethod"add" result=typeof(Employee).InvokeMember("add", BindingFlags.InvokeMethod, null, e, newobject[]{"o1","o2"}, null, null, newstring[]{"key1","key2"}).ToString(); Console.WriteLine("instanceMethod'add'result={0}",result);
//callstaticMethod"add" result=typeof(Employee).InvokeMember("add", BindingFlags.InvokeMethod|BindingFlags.Static|BindingFlags.Public, null, null, newobject[]{"o1","o2","o3"}, null, null, newstring[]{"key1","key2","key3"}).ToString(); Console.WriteLine("staticMethod'add'result={0}",result); Console.WriteLine();
再修改靜態屬性Data,把它從119修改為911
1//callstaticProperty 2i=(int)typeof(Employee).InvokeMember("Data", 3BindingFlags.GetProperty|BindingFlags.Public|BindingFlags.Static, 4null, 5null, 6newobject[]{}); 7Console.WriteLine("staticProperty'Data'={0}",i); 8 9//updatestaticProperty 10typeof(Employee).InvokeMember("data", 11BindingFlags.SetField|BindingFlags.NonPublic|BindingFlags.Static, 12null, 13null, 14newobject[]{911}); 15Console.WriteLine("updatestaticProperty"); 16 17//callstaticProperty 18i=(int)typeof(Employee).InvokeMember("Data", 19BindingFlags.GetProperty|BindingFlags.Public|BindingFlags.Static, 20null, 21null, 22newobject[]{}); 23Console.WriteLine("againcallstaticProperty'Data'={0}",i); 24Console.WriteLine(); 25
再修改實例屬性Name,把它從no 1000修改為w
1//readinstanceProperty 2result=typeof(Employee).InvokeMember("Name", 3BindingFlags.GetProperty, 4null, 5e, 6newobject[]{}).ToString(); 7Console.WriteLine("instanceProperty'Name'={0}",result); 8 9//updateinstanceproperty 10typeof(Employee).InvokeMember("name", 11BindingFlags.SetField|BindingFlags.NonPublic|BindingFlags.Instance, 12null, 13e, 14newobject[]{"w"}); 15Console.WriteLine("updateinstanceproperty"); 16 17//againcallreadinstanceProperty 18result=typeof(Employee).InvokeMember("Name", 19BindingFlags.GetProperty, 20null, 21e, 22newobject[]{}).ToString(); 23Console.WriteLine("againcallinstanceProperty'Name'={0}",result); 24Console.WriteLine(); 25
再修改索引器,把索引器的第2個(index[1])內容修改為222 注意修改索引器的InvokeMember方法,第5個參數的數組new object[]{"002","222"} 将要设置元素的索引值放在对象数组的第一个元素中,将要设置的值作为第二个元素
1//callindex[1] 2result=typeof(Employee).InvokeMember("Item", 3BindingFlags.GetProperty, 4null, 5e, 6newobject[]{1}).ToString(); 7Console.WriteLine("index[1]={0}",result); 8 9//updateindex[1] 10typeof(Employee).InvokeMember("Item", 11BindingFlags.SetProperty, 12null, 13e, 14newobject[]{"002","222"}); 15Console.WriteLine("updateindex[1]"); 16 17//againcallindex[1] 18result=typeof(Employee).InvokeMember("Item", 19BindingFlags.GetProperty, 20null, 21e, 22newobject[]{1}).ToString(); 23 24Console.WriteLine("againcallindex[1]={0}",result); 25Console.WriteLine(); 26
方法2是使用MethodInfo对象上的Invoke方法:
1//callInstanceMethod'add' 2MethodInfomethodInfo1=t.GetMethod("add",BindingFlags.Instance|BindingFlags.Public); 3//InstanceMethod,firstparameterisoneInstance 4result=methodInfo1.Invoke(newEmployee(1,""),newobject[]{"key1","key2"}).ToString(); 5Console.WriteLine("callInstanceMethod'add'result={0}",result); 6 7//callStaticMethod'add' 8MethodInfomethodInfo2=t.GetMethod("add",BindingFlags.Static|BindingFlags.Public); 9//StaticMethod,firstparameterisNull 10result=methodInfo2.Invoke(null,newobject[]{"key1","key2","key3"}).ToString(); 11Console.WriteLine("callStaticMethod'add'result={0}",result); 12
結果圖片:
|
相关推荐
在深入探讨如何通过反射获取实体类的字段和值之前,我们先来理解一下反射是什么以及它在.NET框架中的作用。反射是一种强大的编程技术,允许运行时动态地获取类型的信息并操作对象。它提供了对程序集、模块、类型、...
在C#编程中,反射是一个强大的工具,它允许程序在运行时检查自身并执行与类型相关的操作,如创建对象、访问字段、调用方法等。在本案例中,我们将探讨如何利用反射功能在C# 2.0中给类的属性赋值,特别是在处理数据库...
`Field`类代表类的字段,通过`Class`对象的`getDeclaredFields()`方法获取所有字段,然后调用`set()`和`get()`方法进行读写操作。 4. **调用方法**:`Method`类表示类的方法,`getMethod()`或`getDeclaredMethod()`...
在C#中,反射允许程序在运行时检查自身,获取类型信息(包括类、结构、接口、枚举等),创建实例,调用方法,访问字段和属性。通过`System.Type`类,我们可以获取任何类型的信息,并使用`Activator.CreateInstance()...
Go语言中的反射(Reflection)是一种强大的运行时特性,允许程序在运行时检查、修改和动态调用变量和函数。反射在处理结构体时特别有用,因为它可以让我们在不事先知道结构体确切类型的情况下,访问和修改结构体字段...
7. 通过反射调用方法(GetName和GetDuration)。 尽管反射功能非常强大,但它也有一些缺点。反射操作通常比直接代码访问要慢,并且使用反射时代码的可读性和可维护性可能会降低。此外,反射的动态特性可能导致...
2. **可包含抽象成员**:抽象类可以包含抽象方法、抽象属性、抽象索引器和抽象事件,这些成员没有具体的实现。 3. **不能被sealed修饰**:抽象类不能同时被标记为`sealed`,意味着它必须可以被继承。 4. **子类需...
反射是C#语言的一个强大特性,它允许运行时检查类型信息、获取类的成员(如字段、方法、属性等)并调用它们。这在动态编程场景下尤其有用,比如构建通用的代码库或框架。 #### 获取类型信息 在遍历对象属性之前,...
- **成员**: 抽象类可以拥有字段、属性、构造函数、方法、索引器和事件,而接口只包含抽象方法、属性、索引器和事件。 - **实现**: 抽象类中的成员可以部分实现,接口中的成员则必须全部实现。 - **继承**: 类只能...
Java中的反射机制是Java语言的一项强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这一机制为Java提供了高度的灵活性,使得代码能够根据环境或条件进行自我...
在Java编程中,反射是一种强大的工具,它允许程序在运行时检查类、接口、字段和方法的信息,并能动态地调用方法和修改字段值。在处理数组时,反射也能提供灵活的操作方式。本文将详细解释如何在Java反射中操作数组。...
在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时访问类的信息,并能够动态地创建对象、调用方法以及获取字段值等。这种能力对于框架设计、代码生成等场景具有重要意义。 #### 二、反射...
此外,反射能够调用类型的方法或访问其字段和属性。通过反射,开发者可以编写更灵活和通用的代码。 三、属性(Property) 属性是类、结构和接口中的命名成员。它们扩展了域(Field),并使用相同的语法进行访问。属性...
反射的概述:Java反射机制是指在运行状态中,程序可以获取到关于类、接口、字段和方法的完整信息,并能动态地创建对象和调用其方法。这一机制最早由编程人员Smith在1982年提出。通过反射,开发者可以在不知道具体...
反射是Java的一种强大的工具,它允许程序在运行时检查类、接口、字段和方法的信息,甚至可以在运行时动态创建对象和调用方法。在这个自定义的LinkedList中,反射可能被用来在运行时动态地处理不同类型的数据。例如,...
接口可包含方法、属性、索引器和事件,但无字段和构造函数。 16. 类与结构: 类是引用类型,支持继承和多态;结构是值类型,不支持继承,但可实现接口。 17. 接口多继承问题: 接口可以多继承,可能导致“菱形...
4. **反射技术**:利用Java反射机制获取目标类的方法和字段信息,并通过调用这些方法或访问这些字段来实现对应用的动态修改。 5. **Class Loader的修正**:由于不同的应用可能使用不同的ClassLoader来加载类,因此...
7. **反射**:Java反射机制允许在运行时检查类、接口、字段和方法的信息,甚至可以动态创建对象和调用方法。 8. **泛型**:泛型引入了类型参数,提高了代码的类型安全性和可读性,避免了强制类型转换。 9. **...
在`JDK5.0新特性 (2)——反射.doc`中,你可能会学习到如何使用`java.lang.Class`对象来获取类信息,以及如何使用`java.lang.reflect`包中的`Constructor`、`Method`和`Field`类来操作类的构造器、方法和字段。反射的...