我也来说说Dynamic
看了很多人討論Dynamic。不禁自己也想挖掘下。下面把自己的體會分享給大家
?
1.Dynamic關鍵字是為了方便訪問某個對象。而跟DLR沒太大關系。
使用了dynamic關鍵字創建的對象實際上是一個object. 使用.net 4.0以下的Reflector就可以看到.
使用dynamic關鍵字后編譯器將會將這個對象后面的PropertyName翻譯成相應Binder調用。因此語法檢查器會忽略檢查此對象是否包含PropertyName.
真正的跟DLR有關的是在System.Dynamic下的類型。
大家可以實驗一個叫ExpandoObject的東西
這個時候用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反編譯后
再看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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javascript:jquery.hi
- 下一篇: 读点书吧