zoukankan      html  css  js  c++  java
  • C#动态对象(dynamic)示例(实现方法和属性的动态)

    C#的动态对象的属性实现比较简单,如果要实现动态语言那种动态方法就比较困难,因为对于dynamic对象,扩展方法,匿名方法都是不能用直接的,这里还是利用对象和委托来模拟这种动态方法的实现,看起来有点javascript的对象味道:

    1)定义一个委托,参数个数可变,参数都是object类型:这里的委托多有个dynamic参数,代表调用这个委托的动态对象本身.

    1. publicdelegateobject MyDelegate(dynamic Sender, paramsobject[] PMs); 
    public delegate object MyDelegate(dynamic Sender, params object[] PMs);

    2)定义一个委托转载对象,因为dynamic对象不能直接用匿名方法,这里用对象去承载:

    1. publicclass DelegateObj 
    2.     { 
    3.         private MyDelegate _delegate; 
    4.  
    5.         public MyDelegate CallMethod 
    6.         { 
    7.             get { return _delegate; } 
    8.         } 
    9.         private DelegateObj(MyDelegate D) 
    10.         { 
    11.             _delegate = D; 
    12.         } 
    13.         /// <summary> 
    14.         /// 构造委托对象,让它看起来有点javascript定义的味道. 
    15.         /// </summary> 
    16.         /// <param name="D"></param> 
    17.         /// <returns></returns> 
    18.         publicstatic DelegateObj Function(MyDelegate D) 
    19.         { 
    20.             returnnew DelegateObj(D); 
    21.         } 
    22.     } 
    public class DelegateObj
        {
            private MyDelegate _delegate;
    
            public MyDelegate CallMethod
            {
                get { return _delegate; }
            }
            private DelegateObj(MyDelegate D)
            {
                _delegate = D;
            }
            /// <summary>
            /// 构造委托对象,让它看起来有点javascript定义的味道.
            /// </summary>
            /// <param name="D"></param>
            /// <returns></returns>
            public static DelegateObj Function(MyDelegate D)
            {
                return new DelegateObj(D);
            }
        }
    
    

    3) 定义一个动态对象:

    1. publicclass DynObj : DynamicObject 
    2.     { 
    3.         //保存对象动态定义的属性值 
    4.         private Dictionary<string, object> _values; 
    5.         public DynObj() 
    6.         { 
    7.             _values = new Dictionary<string, object>(); 
    8.         } 
    9.         /// <summary> 
    10.         /// 获取属性值 
    11.         /// </summary> 
    12.         /// <param name="propertyName"></param> 
    13.         /// <returns></returns> 
    14.         publicobject GetPropertyValue(string propertyName) 
    15.         { 
    16.             if (_values.ContainsKey(propertyName) == true
    17.             { 
    18.                 return _values[propertyName]; 
    19.             } 
    20.             returnnull
    21.         } 
    22.         /// <summary> 
    23.         /// 设置属性值 
    24.         /// </summary> 
    25.         /// <param name="propertyName"></param> 
    26.         /// <param name="value"></param> 
    27.         publicvoid SetPropertyValue(string propertyName,object value) 
    28.         { 
    29.             if (_values.ContainsKey(propertyName) == true
    30.             { 
    31.                 _values[propertyName] = value; 
    32.             } 
    33.             else 
    34.             { 
    35.                 _values.Add(propertyName, value); 
    36.             } 
    37.         } 
    38.         /// <summary> 
    39.         /// 实现动态对象属性成员访问的方法,得到返回指定属性的值 
    40.         /// </summary> 
    41.         /// <param name="binder"></param> 
    42.         /// <param name="result"></param> 
    43.         /// <returns></returns> 
    44.         publicoverridebool TryGetMember(GetMemberBinder binder, outobject result) 
    45.         { 
    46.             result = GetPropertyValue(binder.Name); 
    47.             return result == null ? false : true
    48.         } 
    49.         /// <summary> 
    50.         /// 实现动态对象属性值设置的方法。 
    51.         /// </summary> 
    52.         /// <param name="binder"></param> 
    53.         /// <param name="value"></param> 
    54.         /// <returns></returns> 
    55.         publicoverridebool TrySetMember(SetMemberBinder binder, object value) 
    56.         { 
    57.             SetPropertyValue(binder.Name, value); 
    58.             returntrue
    59.         } 
    60.         /// <summary> 
    61.         /// 动态对象动态方法调用时执行的实际代码 
    62.         /// </summary> 
    63.         /// <param name="binder"></param> 
    64.         /// <param name="args"></param> 
    65.         /// <param name="result"></param> 
    66.         /// <returns></returns> 
    67.         publicoverridebool TryInvokeMember(InvokeMemberBinder binder, object[] args, outobject result) 
    68.         { 
    69.             var theDelegateObj = GetPropertyValue(binder.Name) as DelegateObj; 
    70.             if (theDelegateObj == null || theDelegateObj.CallMethod == null
    71.             { 
    72.                 result = null
    73.                 returnfalse
    74.             } 
    75.             result = theDelegateObj.CallMethod(this,args); 
    76.             returntrue
    77.         } 
    78.         publicoverridebool TryInvoke(InvokeBinder binder, object[] args, outobject result) 
    79.         { 
    80.             returnbase.TryInvoke(binder, args, out result); 
    81.         } 
    82.     } 
    public class DynObj : DynamicObject
        {
            //保存对象动态定义的属性值
            private Dictionary<string, object> _values;
            public DynObj()
            {
                _values = new Dictionary<string, object>();
            }
            /// <summary>
            /// 获取属性值
            /// </summary>
            /// <param name="propertyName"></param>
            /// <returns></returns>
            public object GetPropertyValue(string propertyName)
            {
                if (_values.ContainsKey(propertyName) == true)
                {
                    return _values[propertyName];
                }
                return null;
            }
            /// <summary>
            /// 设置属性值
            /// </summary>
            /// <param name="propertyName"></param>
            /// <param name="value"></param>
            public void SetPropertyValue(string propertyName,object value)
            {
                if (_values.ContainsKey(propertyName) == true)
                {
                    _values[propertyName] = value;
                }
                else
                {
                    _values.Add(propertyName, value);
                }
            }
            /// <summary>
            /// 实现动态对象属性成员访问的方法,得到返回指定属性的值
            /// </summary>
            /// <param name="binder"></param>
            /// <param name="result"></param>
            /// <returns></returns>
            public override bool TryGetMember(GetMemberBinder binder, out object result)
            {
                result = GetPropertyValue(binder.Name);
                return result == null ? false : true;
            }
            /// <summary>
            /// 实现动态对象属性值设置的方法。
            /// </summary>
            /// <param name="binder"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public override bool TrySetMember(SetMemberBinder binder, object value)
            {
                SetPropertyValue(binder.Name, value);
                return true;
            }
            /// <summary>
            /// 动态对象动态方法调用时执行的实际代码
            /// </summary>
            /// <param name="binder"></param>
            /// <param name="args"></param>
            /// <param name="result"></param>
            /// <returns></returns>
            public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
            {
                var theDelegateObj = GetPropertyValue(binder.Name) as DelegateObj;
                if (theDelegateObj == null || theDelegateObj.CallMethod == null)
                {
                    result = null;
                    return false;
                }
                result = theDelegateObj.CallMethod(this,args);
                return true;
            }
            public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
            {
                return base.TryInvoke(binder, args, out result);
            }
        }

    应用测试代码:

    1. dynamic theObj = new DynObj(); 
    2.            theObj.aaa = "this is a test";//动态属性 
    3.            //动态方法,这里不能没法定义参数,调用的时候可以是任意多参数,具体参数类型和含义就只能自己去小心处理了. 
    4.            theObj.show = DelegateObj.Function((s, pms) => 
    5.            { 
    6.                if (pms != null && pms.Length > 0) 
    7.                { 
    8.                    MessageBox.Show(pms[0].ToString() + ":" + s.aaa); 
    9.                } 
    10.                else 
    11.                { 
    12.                    MessageBox.Show(s.aaa); 
    13.                } 
    14.                returnnull
    15.            } 
    16.            ); 
    17.            theObj.show("hello"); 
     dynamic theObj = new DynObj();
                theObj.aaa = "this is a test";//动态属性
                //动态方法,这里不能没法定义参数,调用的时候可以是任意多参数,具体参数类型和含义就只能自己去小心处理了.
                theObj.show = DelegateObj.Function((s, pms) =>
                {
                    if (pms != null && pms.Length > 0)
                    {
                        MessageBox.Show(pms[0].ToString() + ":" + s.aaa);
                    }
                    else
                    {
                        MessageBox.Show(s.aaa);
                    }
                    return null;
                }
                );
                theObj.show("hello");

    虽然看起来上面有点Js定义对象方法的味道,但由于C#是静态语言,提供的动态模拟机制还是有限的,看起来是动态,但所有的值存放和方法都需要自己写代码去处理.

    以上代码在vs2010,windows 2008 server,框架4.0 上测试OK.

    转自:http://blog.csdn.net/hawksoft/article/details/7534332

  • 相关阅读:
    用dt命令搜索查看符号
    烦人的异常
    _NT_SYMBOL_PROXY
    Windbg常用命令系列---.f+, .f- (切换Local Context)
    Windbg常用命令系列---.dumpcab (创建dump CAB文件)
    Windbg常用命令系列---.dump(创建dump文件)
    Windbg常用命令系列---!mapped_file
    Windbg常用命令系列---!cppexr
    再谈FPO
    Windbg常用命令系列---!stl
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/3314752.html
Copyright © 2011-2022 走看看