a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C# > 正文

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

2020-01-24 03:20:27
字體:
來源:轉載
供稿:網友

接上文:C# Dynamic關鍵字之:ExpandoObject,DynamicObject,DynamicMetaOb的應用(上)

為什么TryXXX方法沒有被調用??

將DynamicProduct 中的name修飾符改為private:

private string name;

可以在TrySetMember方法中設置斷點,再次運行:

image

clip_image002

clip_image004

為什么訪問修飾符是Public不調用TrySetMember,是Private 就調用了呢??

難道是因為private拋出了異常嗎??

再次看看Msdn對此的TrySetMember方法的解釋:

Msdn備注

…………….動態語言運行庫 (DLR) 將首先使用語言聯編程序在類中查找屬性的靜態定義。 如果沒有此類屬性,DLR 調用 TrySetMember 方法。

問題的原因是這樣的:首先DLR 使用語言聯編程序在類中查找name的靜態定義,

因為name是public,所以查找到了,然后返回,不會去調用TrySetMember方法了,

但是如果name是private,那么聯編程序在類中沒找到name的靜態定義,于是DLR嘗試調用TrySetMember方法。

修改TrySetMember方法如下:

復制代碼 代碼如下:

public override bool TrySetMember(SetMemberBinder binder, object value)
{
    Console.WriteLine("TrySetMember被調用了,Name:{0}", binder.Name);
    bool result = base.TrySetMember(binder, value);

    return true;
}



運行,可以發現不會拋出異常了:

clip_image002[5]

總結:首先DLR會嘗試查找屬性的靜態定義,如果沒有找到則會調用相應的TryXXX 方法,如果TryXXX方法返回false,代表TryXXX方法運行失敗,DLR隨后會拋出異常。

為了驗證是不是這樣,將DynamicProduct中屬性的靜態定義全部注釋掉,并且TryXXX方法全部返回True。完整的代碼如下:

復制代碼 代碼如下:

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方法不變:
復制代碼 代碼如下:

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();
}

運行,結果如下:

clip_image002[9]

d.P3 = d.M1(d.P1, d.M2(d.P2));

按照從左到右,從里到外的原則。

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 方法。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产精品色综合 | 久久综合一区二区 | 欧洲在线一区 | 日韩欧美一区二区在线 | 亚洲欧美一区二区三区久久 | 久久久久女人精品毛片九一韩国 | 中文字幕日韩欧美 | av日韩在线播放 | 日韩福利视频 | 日韩超级毛片 | 日韩啊v| 精品一区二区三区四区 | 国产精品理论片 | 国产欧美一区二区在线观看 | 日韩电影免费观看 | 久久91| 久久久久av| 国产成人久久 | 亚洲精品一区二区三区 | 男女瑟瑟| 日本少妇视频 | √新版天堂资源在线资源 | 国产精品美女久久久久久久网站 | 碰视频| 欧美成人免费 | 日韩二区 | 国产精品日韩 | 99精品国产高清一区二区麻豆 | 久久九九免费 | 国产午夜精品一区二区 | 日本三级在线观看中文字 | 久久久久国产精品午夜一区 | 日韩视频精品在线 | 欧美精品1区2区 | 欧美日韩在线精品 | 精品国产乱码久久久久久蜜柚 | 五月婷婷丁香 | 久久久免费观看视频 | 成人爽a毛片一区二区免费 美女一级毛片 | 欧美一级二级三级 | 国产一区|