• 热门专题

利用反射方法(Type.InvokeMember)取得不同数据对象属性

作者:  发布日期:2012-09-13 11:43:19
Tag标签:反射方法  
  • 使用Type.InvokeMember方法可以在执行时期动态系结对象属性或方法,
    举个例子来说明,
    我有两个不同的数据对象和一个输出方法,两个数据对象将由使用者在执行时期的操作而产生对应的数据对象,
    并且使用同一个输出方法来打印数据对象的值,该怎么做呢? 下面来实作一下。
    先建立两个 value object

     

    public class UserVo
    {
        private string _name;
        public string name
        {
            get { return _name; }
            set { 
                _name = value;
                _PropertyNames.Add("name");
            }
        }
    
        private List<string> _PropertyNames = new List<string>();
        public List PropertyNames
        {
            get { return _PropertyNames; }
            set { _PropertyNames = value; }
        }
    
        public object GetPropertyValue(string propName)
        {
            switch (propName)
            {
                case "name":
                    return name;
                default:
                    return "";
            }
        }
    }
    

    public class ProductVo
    {
        private int _pid;
        public int pid
        {
            get { return _pid; }
            set {
                _pid = value;
                _PropertyNames.Add("pid");
            }
        }
    
        private string _proName;
        public string proName
        {
            get { return _proName; }
            set { 
                _proName = value;
                PropertyNames.Add("proName");
            }
        }
    
        private List _PropertyNames = new List();
        public List PropertyNames
        {
            get { return _PropertyNames; }
            set { _PropertyNames = value; }
        }
    
        public object GetPropertyValue(string propName)
        {
            switch (propName)
            {
                case "pid":
                    return pid;
                case "proName":
                    return proName;
                default:
                    return "";
            }
        }
    }

    在这两个数据对象中,除了本身的一些属性之外,我额外增加了 PropertyNams属性跟 GetPropertyValue方法PropertyNams 属性用来存放有给予值的属性名称以便于之后调用。
    GetPropertyValue 方法用来取得与属性名称对应之值。
    在将数据对象处理完成后,就要来实际使用 InvokeMember 方法在执行时期将产生的对象属性显示,建立一个 aspx 网页,并在画面上拖入两个按钮

     
     

    切换到后置程序代码画面,在两个按钮事件中分别建立不同的数据对象,并将对象传至PrintData方法www.it165.net

     

    protected void Button1_Click(object sender, EventArgs e)
        {
            UserVo myVo = new UserVo();
            myVo.name = "Arvin";
            PrintData(myVo);
        }
    
        protected void Button2_Click(object sender, EventArgs e)
        {
            ProductVo myVo = new ProductVo();
            myVo.pid = 101000001;
            myVo.proName = "Product_101";
            PrintData(myVo);
        }

    在此使用 Type.InvokeMember 方法 (String, BindingFlags, Binder, Object, Object[])

    语法如下:


    public Object InvokeMember(
    	string name,
    	BindingFlags invokeAttr,
    	Binder binder,
    	Object target,
    	Object[] args
    )
    

    • name: 要呼叫的属性或方法名称
    • invokeAttr: 位屏蔽,如BindingFlags.GetProperty(取属性)或BindingFlags.InvokeMethod(叫用方法)等...
    • binder: 定义一组属性并启用系结的对象
    • target: 要呼叫的该对象成员
    • args: 要传入呼叫的成员的自变量数组

    在PrintData方法中,先使用 getType() 取得该对象型别,因为了让PrintData方法于不同的数据对象都能使用,传入的数据对象是使用object去接收,
    取得了 objType 之后,使用反射的方式将数据对象的PropertyNames属性取得,invokeAttr参数使用的是 BindingFlags.GetProperty
    而取得了PropertyNames后就可以使用循环将资料读出,而在读取数据时将 invokeAttr参数改成 BindingFlags.InvokeMethod 则变成呼叫方法

     

    private void PrintData(object objVo)
        {
            Type objType = objVo.GetType();
            // 取得属性名称集合
            List names = (List)objType.InvokeMember("PropertyNames", System.Reflection.BindingFlags.GetProperty, null, objVo, new object[] { });
            // 将所有属性值印出
            foreach (string name in names)
            {
                Response.Write(objType.InvokeMember("GetPropertyValue", System.Reflection.BindingFlags.InvokeMethod, null, objVo, new object[] { name }) + "
    ");
            }
        }
    

    完成后,实际执行结果如下


     

    另外补充一下,在.NET Framework 4.0 C#中多了 dynamic 型别,
    如果在此将PrintData的传入参数改成 dynamic 型别后,呼叫成员的方法就可以不使用反射的方式,
    可以直接叫用该方法即可。

延伸阅读:

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规