C#的动态对象的属性完成比较简单,假如要完成动态言语那种动态要领就比较难题,由于关于dynamic对象,扩大要领,匿名要领都是不能用直接的,这里照样运用对象和托付来模仿这类动态要领的完成,看起来有点javascript的对象滋味:
1) 定义一个托付,参数个数可变,参数都是object范例:这里的托付多有个dynamic参数,代表挪用这个托付的动态对象自身。
public delegate object MyDelegate(dynamic Sender, params object[] PMs);
2) 定义一个托付转载对象,由于dynamic对象不能直接用匿名要领,这里用对象去承载:
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) 定义一个动态对象:
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); } }
运用测试代码:
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.
以上就是C#动态对象dynamic完成要领和属性动态代码详解的细致内容,更多请关注ki4网别的相干文章!