日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

我也来说说Dynamic

發布時間:2024/4/17 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我也来说说Dynamic 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

看了很多人討論Dynamic。不禁自己也想挖掘下。下面把自己的體會分享給大家

?

1.Dynamic關鍵字是為了方便訪問某個對象。而跟DLR沒太大關系。

使用了dynamic關鍵字創建的對象實際上是一個object. 使用.net 4.0以下的Reflector就可以看到.

使用dynamic關鍵字后編譯器將會將這個對象后面的PropertyName翻譯成相應Binder調用。因此語法檢查器會忽略檢查此對象是否包含PropertyName.

真正的跟DLR有關的是在System.Dynamic下的類型。

大家可以實驗一個叫ExpandoObject的東西

private static void Main(string[] args) { dynamic expandoObject = new ExpandoObject(); expandoObject.PropertyA = "PropertyA";expandoObject.PropertyB = 2010; Console.WriteLine(expandoObject.PropertyA);Console.WriteLine(expandoObject.PropertyB); }


這個時候用dynamic是不是有點動態語言的感覺了?所以說 dynamic不是DLR的實現,
但要用DLR在C#里最好的途徑可能就是使用dynimic了。


?

2.Dynamic關鍵字是一個編譯器做的語法糖

?

請看如下代碼:

原始代碼

? public class Program{static void Main(string[] args){Method1();Method2();Method3();Method4();}private static void Method1(){dynamic d = new TestClass();d.TestProperty = "";}private static void Method2(){TestClass t = new TestClass();dynamic d1 = t;dynamic d2 = t;d1.TestProperty = "";d2.TestProperty = "";}private static void Method3(){dynamic d = new TestClass();for (int i = 0; i < 100; i++){d.TestProperty = i.ToString();}}private static void Method4(){for (int i = 0; i < 100; i++){dynamic d = new TestClass();d.TestProperty = i.ToString();}}class TestClass{public string TestProperty { get; set; }}


用3.5語法反編譯的
其實上面也都說的很清楚了 編譯器會把dynamic編譯在一個和dynamic所在函數名有關的Static SiteContainer

<Method1>o__SiteContainer0
<Method2>o__SiteContainer2 …等

?

而且是一個dynamic生成一個Site .裝在對應的Container中。

下面我們來看Method1 反編譯后

? private static void Method1() {object d = new TestClass();if (<Method1>o__SiteContainer0.<>p__Site1 == null){<Method1>o__SiteContainer0.<>p__Site1 = CallSite<Func<CallSite, object, string, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "TestProperty", typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) }));}<Method1>o__SiteContainer0.<>p__Site1.Target(<Method1>o__SiteContainer0.<>p__Site1, d, ""); }

可以看出d其實是個Object了訪問屬性通過Site實現,而且這里的Site判空,意味著可以緩存。

Method2反編譯后

private static void Method2() {TestClass t = new TestClass();object d1 = t;object d2 = t;if (<Method2>o__SiteContainer2.<>p__Site3 == null){<Method2>o__SiteContainer2.<>p__Site3 = CallSite<Func<CallSite, object, string, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "TestProperty", typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) }));}<Method2>o__SiteContainer2.<>p__Site3.Target(<Method2>o__SiteContainer2.<>p__Site3, d1, "");if (<Method2>o__SiteContainer2.<>p__Site4 == null){<Method2>o__SiteContainer2.<>p__Site4 = CallSite<Func<CallSite, object, string, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "TestProperty", typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null) }));}<Method2>o__SiteContainer2.<>p__Site4.Target(<Method2>o__SiteContainer2.<>p__Site4, d2, ""); }雖然 d1 d2 都指向了 同一個對象t.但這里還是創建了兩個Site。可見出現了多少個dynamic就會創建多少個site.

再看Method3和Method4? private static void Method3(){object d = new TestClass();for (int i = 0; i < 100; i++){if (<Method3>o__SiteContainer5.<>p__Site6 == null){<Method3>o__SiteContainer5.<>p__Site6 = CallSite<Func<CallSite, object, string, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "TestProperty", typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) }));}<Method3>o__SiteContainer5.<>p__Site6.Target(<Method3>o__SiteContainer5.<>p__Site6, d, i.ToString());}}private static void Method4(){for (int i = 0; i < 100; i++){object d = new TestClass();if (<Method4>o__SiteContainer7.<>p__Site8 == null){<Method4>o__SiteContainer7.<>p__Site8 = CallSite<Func<CallSite, object, string, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "TestProperty", typeof(Program), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null) }));}<Method4>o__SiteContainer7.<>p__Site8.Target(<Method4>o__SiteContainer7.<>p__Site8, d, i.ToString());}}


可見dynamic寫在循環里和循環外都是一樣的。因為編譯器只看到一個dynamic。只生成了一個site.由于site一樣且經過緩存,
可以猜想性能不會相差太。

3.Dynamic做了會做緩存,加速訪問

由于Site和SiteContainer都是Staic的,所以凡是重復對一個dynamic操作多次都會受益于這種cache。眼看要下班了。筆先收一下,有時間再寫:-)

轉載于:https://www.cnblogs.com/Gerryz/archive/2010/12/14/1905909.html

總結

以上是生活随笔為你收集整理的我也来说说Dynamic的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。