您的位置:首页 > 编程语言 > C#

C# 高级应用--反射动态调用类的成员范例 !

2009-08-31 11:00 573 查看
//-----------------------------------------------------------测试类-------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InvokeMemberDemo
{
/// <summary>
///  有关用户信息的相关类
/// </summary>
class UserInfo
{
//私有字段及公有属性
private int carID = 0;
public int CarID
{
get { return carID; }
set { carID = value; }
}

//公有属性
public string userName = "";

//默认构造及带参构造
public UserInfo() { }
public UserInfo(int id, string name)
{
this.carID = id;
this.userName = name;
}

//有返回值的方法
public string GetName(string name)
{
return name;
}

//无返回值的方法
public void GetID()
{
Console.WriteLine("carID : "+this.carID.ToString());
}

}
}


//----------------------------------------------------------------测试代码--------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Reflection;                                                    //引入反射的命名空间
using System.Collections;

namespace InvokeMemberDemo
{
class Program
{
static void Main(string[] args)
{
UserInfo myUser = new UserInfo();                        //创建用户信息实例
Type myType = myUser.GetType();                         //获得创建实例的类型
object[] myparam = new object[] { 610430, "sa" };  //参数列表

/*
* 有关反射调用成员的方法的一些参数的相关说明
* public object InvokeMember(
*           string name,                      要调用的构造函数、方法、属性或字段成员的名称
*           BindingFlags invokeAttr,    由一个或多个指定搜索执行方式的 BindingFlags 组成
*           Binder binder,                    涉及选择重载方法、强制参数类型和通过反射调用成员
*           object target,                     要在其上调用指定成员的 Object
*           object[] args                       包含传递给要调用的成员的参数的数组
* );
* 表示被调用成员的返回值的 Object。
* */
#region 备注
/*
下列 BindingFlags 筛选标志可用于【定义包含在搜索中的成员】:

为了获取返回值,必须指定 BindingFlags.Instance 或 BindingFlags.Static。
指定 BindingFlags.Public 可在搜索中包含公共成员。
指定 BindingFlags.NonPublic 可在搜索中包含非公共成员(即私有成员和受保护的成员)。
指定 BindingFlags.FlattenHierarchy 可包含层次结构上的静态成员。

下列 BindingFlags 修饰符标志可用于【更改搜索的执行方式】:

BindingFlags.IgnoreCase,表示忽略 name 的大小写。
BindingFlags.DeclaredOnly,仅搜索 Type 上声明的成员,而不搜索被简单继承的成员。

可以使用下列 BindingFlags 调用标志表示要【对成员采取的操作】:

CreateInstance,表示调用构造函数。忽略 name。对其他调用标志无效。
InvokeMethod,表示调用方法,而不调用构造函数或类型初始值设定项。对 SetField 或 SetProperty 无效。
GetField,表示获取字段值。对 SetField 无效。
SetField,表示设置字段值。对 GetField 无效。
GetProperty,表示获取属性。对 SetProperty 无效。
SetProperty 表示设置属性。对 GetProperty 无效。
*/

#endregion

#region 调用带参构造函数创建该对象的反射实例!
Console.WriteLine("调用带参构造函数创建该对象的反射实例!");
object userObj = myType.InvokeMember
(null,
BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.CreateInstance, null, null, myparam);
Console.WriteLine("userObj : "+userObj.GetType().FullName);
Console.WriteLine();
#endregion

#region 设置字段值并获得该字段的值
Console.WriteLine("设置字段值并获得该字段的值 !");
myType.InvokeMember(
"userName",
BindingFlags.SetField,
null,
userObj,
new object[] { "myName" });
Console.WriteLine("字段:userName, 设置完成!");

string userName = (string)myType.InvokeMember(
"userName",
BindingFlags.GetField,
null,
userObj,
null);
Console.WriteLine("userName: "+userName);
Console.WriteLine();
#endregion

#region 设置属性值并获得该属性的值
Console.WriteLine("设置属性值并获得该属性的值 !");
myType.InvokeMember(
"CarID",
BindingFlags.SetProperty,
null,
userObj,
new object[] {610430});
Console.WriteLine("属性:CarID,设置完成!");

int carID = (int)myType.InvokeMember(
"CarID",
BindingFlags.GetProperty,
null,
userObj,
null);
Console.WriteLine("CarID: " + carID);
Console.WriteLine();
#endregion

#region 调用有返回值的方法
Console.WriteLine("调用有返回值的方法 !");
string GetName = (string)myType.InvokeMember(
"GetName",
BindingFlags.InvokeMethod |
BindingFlags.Public |
BindingFlags.Instance,
null,
userObj,
new object[] {"MyName"});
Console.WriteLine("GetName: "+GetName);
Console.WriteLine();
#endregion

#region 调用无返回值的方法
Console.WriteLine("调用无返回值的方法 !");
myType.InvokeMember(
"GetID",
BindingFlags.InvokeMethod |
BindingFlags.Public |
BindingFlags.Instance,
null,
userObj,
null);
Console.WriteLine();
#endregion

#region 动态装载指定实例的反射数据对象并解析数据
ArrayList myList = new ArrayList();

//装载数据对象
for (int i = 1; i < 11; i++)
{
myparam = new object[] {i, "name"+i };

userObj = myType.InvokeMember
(null,
BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance |
BindingFlags.CreateInstance, null, null, myparam);
myList.Add(userObj);
}

//便利数据对象
foreach(object var in myList)
{
string userNames = (string)myType.InvokeMember(
"userName",
BindingFlags.GetField,
null,
var,
null);
Console.WriteLine("userNames: " + userNames);
}
#endregion
Console.ReadLine();    //暂停

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐