源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

C# Dynamic之:ExpandoObject,DynamicObject,DynamicMetaOb的应用(下)

  • 时间:2021-04-21 05:18 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:C# Dynamic之:ExpandoObject,DynamicObject,DynamicMetaOb的应用(下)
接上文:C# Dynamic关键字之:[url=http://www.1sucai.cn/article/36781.htm]ExpandoObject,DynamicObject,DynamicMetaOb的应用(上) [/url] [b]为什么TryXXX方法没有被调用?? [/b] 将DynamicProduct 中的name修饰符改为private: private string name; 可以在TrySetMember方法中设置断点,再次运行: [img]http://files.jb51.net/file_images/article/201305/2013051409415429.png[/img] [img]http://files.jb51.net/file_images/article/201305/2013051409415430.jpg[/img] [img]http://files.jb51.net/file_images/article/201305/2013051409415431.jpg[/img] 为什么访问修饰符是Public不调用TrySetMember,是Private 就调用了呢?? 难道是因为private抛出了异常吗?? 再次看看Msdn对此的TrySetMember方法的解释: [b]Msdn[/b][b]备注[/b][b][/b] …………….[b]动态语言运行库[/b][b] (DLR) [/b][b]将首先使用语言联编程序在类中查找属性的静态定义。[/b][b] [/b][b]如果没有此类属性,[/b][b]DLR [/b][b]调用[/b][b] [/b][b]TrySetMember[/b][b] [/b][b]方法。[/b] [b]问题的原因是这样的[/b]:首先DLR 使用语言联编程序在类中查找name的静态定义, 因为name是public,所以查找到了,然后返回,不会去调用TrySetMember方法了, 但是如果name是private,那么联编程序在类中没找到name的静态定义,于是DLR尝试调用TrySetMember方法。 修改TrySetMember方法如下:
[u]复制代码[/u] 代码如下:
public override bool TrySetMember(SetMemberBinder binder, object value) {     Console.WriteLine("TrySetMember被调用了,Name:{0}", binder.Name);     bool result = base.TrySetMember(binder, value);     return true; }
运行,可以发现不会抛出异常了: [img]http://files.jb51.net/file_images/article/201305/2013051409415432.jpg[/img] [b]总结:[/b]首先DLR会尝试查找属性的静态定义,如果没有找到则会调用相应的TryXXX 方法,如果TryXXX方法返回false,代表TryXXX方法运行失败,DLR随后会抛出异常。 为了验证是不是这样,将DynamicProduct中属性的静态定义全部注释掉,并且TryXXX方法全部返回True。完整的代码如下:
[u]复制代码[/u] 代码如下:
class DynamicProduct : DynamicObject {     #region dynamicProduct 的一些属性的静态定义         //private string name;         //public int Id { get; set; }         //public void ShowProduct()         //{         //    Console.WriteLine("Id={0} ,Name={1}", Id, name);         //}     #endregion     #region Override DynamicObject 的方法     public override bool TryGetMember(GetMemberBinder binder, out object result)     {         Console.WriteLine("TryGetMember被调用了,Name:{0}", binder.Name);         bool tryResult = base.TryGetMember(binder, out result);         return true;     }     public override bool TrySetMember(SetMemberBinder binder, object value)     {         Console.WriteLine("TrySetMember被调用了,Name:{0}", binder.Name);         bool tryResult = base.TrySetMember(binder, value);         return true;     }     public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)     {         Console.WriteLine("TryInvoke被调用了");         bool tryResult = base.TryInvoke(binder, args, out result);         return true;     }     public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)     {         Console.WriteLine("TryInvokeMember被调用了,Name:{0}", binder.Name);         bool tryResult = base.TryInvokeMember(binder, args, out result);         return true;     }     #endregion }
Main方法不变:
[u]复制代码[/u] 代码如下:
static void Main(string[] args) {     dynamic dynProduct = new DynamicProduct();     dynProduct.name = "n1"; //调用TrySetMember方法     dynProduct.Id = 1;     dynProduct.Id = dynProduct.Id + 3;     dynProduct.ShowProduct();     Console.ReadLine(); }
运行,结果如下: [img]http://files.jb51.net/file_images/article/201305/2013051409415434.jpg[/img] [b]d.P3 = d.M1(d.P1, d.M2(d.P2)); [/b] 按照从左到右,从里到外的原则。 1:先调用d.P1,DLR会尝试调用d 的GetMetaObject 方法,此方法返回一个MyMetaObject对象。 接着DLR知道你调用的是一个属性,于是它调用返回的MyMetaObject对象的BindGetMember 方法, 输出为GetMember of property P1 2:调用d.P2,和调用d.P1 一样. 3:调用d.M2,同样DLR调用d的GetMetaObject方法,返回一个MyMetaObject对象,接着调用返回对象的BindInvokeMember 方法。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部