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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

我也来说说Dynamic

發(fā)布時(shí)間:2024/4/17 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 我也来说说Dynamic 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

?

1.Dynamic關(guān)鍵字是為了方便訪問(wèn)某個(gè)對(duì)象。而跟DLR沒(méi)太大關(guān)系。

使用了dynamic關(guān)鍵字創(chuàng)建的對(duì)象實(shí)際上是一個(gè)object. 使用.net 4.0以下的Reflector就可以看到.

使用dynamic關(guān)鍵字后編譯器將會(huì)將這個(gè)對(duì)象后面的PropertyName翻譯成相應(yīng)Binder調(diào)用。因此語(yǔ)法檢查器會(huì)忽略檢查此對(duì)象是否包含PropertyName.

真正的跟DLR有關(guān)的是在System.Dynamic下的類型。

大家可以實(shí)驗(yàn)一個(gè)叫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); }


這個(gè)時(shí)候用dynamic是不是有點(diǎn)動(dòng)態(tài)語(yǔ)言的感覺(jué)了?所以說(shuō) dynamic不是DLR的實(shí)現(xiàn),
但要用DLR在C#里最好的途徑可能就是使用dynimic了。


?

2.Dynamic關(guān)鍵字是一個(gè)編譯器做的語(yǔ)法糖

?

請(qǐng)看如下代碼:

原始代碼

? 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語(yǔ)法反編譯的
其實(shí)上面也都說(shuō)的很清楚了 編譯器會(huì)把dynamic編譯在一個(gè)和dynamic所在函數(shù)名有關(guān)的Static SiteContainer

<Method1>o__SiteContainer0
<Method2>o__SiteContainer2 …等

?

而且是一個(gè)dynamic生成一個(gè)Site .裝在對(duì)應(yīng)的Container中。

下面我們來(lái)看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其實(shí)是個(gè)Object了訪問(wèn)屬性通過(guò)Site實(shí)現(xiàn),而且這里的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 都指向了 同一個(gè)對(duì)象t.但這里還是創(chuàng)建了兩個(gè)Site。可見(jiàn)出現(xiàn)了多少個(gè)dynamic就會(huì)創(chuàng)建多少個(gè)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());}}


可見(jiàn)dynamic寫(xiě)在循環(huán)里和循環(huán)外都是一樣的。因?yàn)榫幾g器只看到一個(gè)dynamic。只生成了一個(gè)site.由于site一樣且經(jīng)過(guò)緩存,
可以猜想性能不會(huì)相差太。

3.Dynamic做了會(huì)做緩存,加速訪問(wèn)

由于Site和SiteContainer都是Staic的,所以凡是重復(fù)對(duì)一個(gè)dynamic操作多次都會(huì)受益于這種cache。眼看要下班了。筆先收一下,有時(shí)間再寫(xiě):-)

轉(zhuǎn)載于:https://www.cnblogs.com/Gerryz/archive/2010/12/14/1905909.html

總結(jié)

以上是生活随笔為你收集整理的我也来说说Dynamic的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。