C# Dynamic之:ExpandoObject,DynamicObject,DynamicMetaOb的應(yīng)用(下)
接上文:C# Dynamic關(guān)鍵字之:ExpandoObject,DynamicObject,DynamicMetaOb的應(yīng)用(上)
為什么TryXXX方法沒有被調(diào)用??
將DynamicProduct 中的name修飾符改為private:
private string name;
可以在TrySetMember方法中設(shè)置斷點(diǎn),再次運(yùn)行:
為什么訪問修飾符是Public不調(diào)用TrySetMember,是Private 就調(diào)用了呢??
難道是因?yàn)閜rivate拋出了異常嗎??
再次看看Msdn對此的TrySetMember方法的解釋:
Msdn備注
…………….動態(tài)語言運(yùn)行庫 (DLR) 將首先使用語言聯(lián)編程序在類中查找屬性的靜態(tài)定義。 如果沒有此類屬性,DLR 調(diào)用 TrySetMember 方法。
問題的原因是這樣的:首先DLR 使用語言聯(lián)編程序在類中查找name的靜態(tài)定義,
因?yàn)閚ame是public,所以查找到了,然后返回,不會去調(diào)用TrySetMember方法了,
但是如果name是private,那么聯(lián)編程序在類中沒找到name的靜態(tài)定義,于是DLR嘗試調(diào)用TrySetMember方法。
修改TrySetMember方法如下:
public override bool TrySetMember(SetMemberBinder binder, object value)
{
Console.WriteLine("TrySetMember被調(diào)用了,Name:{0}", binder.Name);
bool result = base.TrySetMember(binder, value);
return true;
}
運(yùn)行,可以發(fā)現(xiàn)不會拋出異常了:
總結(jié):首先DLR會嘗試查找屬性的靜態(tài)定義,如果沒有找到則會調(diào)用相應(yīng)的TryXXX 方法,如果TryXXX方法返回false,代表TryXXX方法運(yùn)行失敗,DLR隨后會拋出異常。
為了驗(yàn)證是不是這樣,將DynamicProduct中屬性的靜態(tài)定義全部注釋掉,并且TryXXX方法全部返回True。完整的代碼如下:
class DynamicProduct : DynamicObject
{
#region dynamicProduct 的一些屬性的靜態(tài)定義
//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被調(diào)用了,Name:{0}", binder.Name);
bool tryResult = base.TryGetMember(binder, out result);
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
Console.WriteLine("TrySetMember被調(diào)用了,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被調(diào)用了");
bool tryResult = base.TryInvoke(binder, args, out result);
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
Console.WriteLine("TryInvokeMember被調(diào)用了,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"; //調(diào)用TrySetMember方法
dynProduct.Id = 1;
dynProduct.Id = dynProduct.Id + 3;
dynProduct.ShowProduct();
Console.ReadLine();
}
運(yùn)行,結(jié)果如下:
d.P3 = d.M1(d.P1, d.M2(d.P2));
按照從左到右,從里到外的原則。
1:先調(diào)用d.P1,DLR會嘗試調(diào)用d 的GetMetaObject 方法,此方法返回一個(gè)MyMetaObject對象。
接著DLR知道你調(diào)用的是一個(gè)屬性,于是它調(diào)用返回的MyMetaObject對象的BindGetMember 方法,
輸出為GetMember of property P1
2:調(diào)用d.P2,和調(diào)用d.P1 一樣.
3:調(diào)用d.M2,同樣DLR調(diào)用d的GetMetaObject方法,返回一個(gè)MyMetaObject對象,接著調(diào)用返回對象的BindInvokeMember 方法。
- C#動態(tài)對象(dynamic)詳解(實(shí)現(xiàn)方法和屬性的動態(tài))
- C#中Dynamic和Dictionary性能比較
- C#中dynamic關(guān)鍵字的正確用法(推薦)
- 深入C# 4.0 新特性dynamic、可選參數(shù)、命名參數(shù)的詳細(xì)介紹
- C# Dynamic關(guān)鍵字之:dynamic為什么比反射快的詳解
- C# Dynamic之:ExpandoObject,DynamicObject,DynamicMetaOb的應(yīng)用(上)
- C# Dynamic關(guān)鍵字之:調(diào)用屬性、方法、字段的實(shí)現(xiàn)方法
- C# Dynamic關(guān)鍵字之:解析dynamic就是Object
- C# dynamic關(guān)鍵字的使用方法
- C#使用dynamic類型訪問JObject對象
相關(guān)文章
C#利用TreeView控件實(shí)現(xiàn)目錄跳轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了C#潤滑利用TreeView控件實(shí)現(xiàn)目錄跳轉(zhuǎn)功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以動手嘗試一下2022-07-07
C#正則表達(dá)式獲取下拉菜單(select)的相關(guān)屬性值
這篇文章主要介紹了C#正則表達(dá)式獲取下拉菜單(select)的相關(guān)屬性值,比如可以獲得name屬性的值、value值、指定值,需要的朋友可以參考下2014-07-07
C#實(shí)現(xiàn)讀取多條數(shù)據(jù)記錄并導(dǎo)出到Word
這篇文章主要為大家詳細(xì)介紹了C#如何實(shí)現(xiàn)讀取多條數(shù)據(jù)記錄并導(dǎo)出到Word,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
C#實(shí)現(xiàn)簡單的Login窗口實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)簡單的Login窗口,實(shí)例分析了C#顯示及關(guān)閉登陸Login窗口的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-08-08
C#實(shí)現(xiàn)windows form限制文本框輸入的方法
這篇文章主要介紹了C#實(shí)現(xiàn)windows form限制文本框輸入的方法,涉及C#限制文本框輸入的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
.NET實(shí)現(xiàn)父窗體關(guān)閉而不影響子窗體的方法
這篇文章主要介紹了.NET實(shí)現(xiàn)父窗體關(guān)閉而不影響子窗體的方法,很實(shí)用的功能,需要的朋友可以參考下2014-08-08

