我也来说说Dynamic
看了很多人討論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的東西
這個(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反編譯后
再看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)題。
- 上一篇: javascript:jquery.hi
- 下一篇: 读点书吧