• C#动态对象(dynamic)示例(实现方法和属性的动态)


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

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

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

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

     1     public class 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         public static DelegateObj Function(MyDelegate D)  
    19         {  
    20             return new DelegateObj(D);  
    21         }  
    22     }  

    3) 定义一个动态对象:

     1     public class 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         public object GetPropertyValue(string propertyName)  
    15         {  
    16             if (_values.ContainsKey(propertyName) == true)  
    17             {  
    18                 return _values[propertyName];  
    19             }  
    20             return null;  
    21         }  
    22         /// <summary>  
    23         /// 设置属性值  
    24         /// </summary>  
    25         /// <param name="propertyName"></param>  
    26         /// <param name="value"></param>  
    27         public void 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         public override bool TryGetMember(GetMemberBinder binder, out object 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         public override bool TrySetMember(SetMemberBinder binder, object value)  
    56         {  
    57             SetPropertyValue(binder.Name, value);  
    58             return true;  
    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         public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)  
    68         {  
    69             var theDelegateObj = GetPropertyValue(binder.Name) as DelegateObj;  
    70             if (theDelegateObj == null || theDelegateObj.CallMethod == null)  
    71             {  
    72                 result = null;  
    73                 return false;  
    74             }  
    75             result = theDelegateObj.CallMethod(this,args);  
    76             return true;  
    77         }  
    78         public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)  
    79         {  
    80             return base.TryInvoke(binder, args, out result);  
    81         }  
    82     }  

    测试代码:

     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                return null;  
    15            }  
    16            );  
    17            theObj.show("hello");  
  • 相关阅读:
    搭建james邮件服务器
    Spring -- AOP
    【RF库Collections测试】List Should Not Contain Duplicates
    【RF库Collections测试】Keep In Dictionary
    【RF库Collections测试】Insert Into List
    【RF库Collections测试】Get Index From List
    【RF库Collections测试】Get From List
    【RF库Collections测试】Count Values In List
    【RF库Collections测试】Get Slice From List
    【RF库Collections测试】Copy Dictionary
  • 原文地址:https://www.cnblogs.com/yanglang/p/6890733.html
Copyright © 2020-2023  润新知