可以看出生成的IL代碼確實不美觀,不過大體能看出端倪。為 了方便查看,用Reflector查看,把反編譯結果設置為.Net2.0,代碼清晰多了:
01. internal class Program
02. {
03. // Methods
04. private static void Main()
05. {
06. object d = "str";
07. if (<Main>o__SiteContainer0.<>p__Site1 == null)
08. {
09. <Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.
10. Create(new CSharpInvokeMemberBinder(CSharpCallFlags.None, "ToString", typeof(Program),
11. null, new CSharpArgumentInfo[] { new CSharpArgumentInfo (CSharpArgumentInfoFlags.None, null) }));
12. }
13. <Main>o__SiteContainer0.<>p__Site1.Target (<Main>o__SiteContainer0.<>p__Site1, d);
14. }
15. // Nested Types
16. [CompilerGenerated]
17. private static class <Main>o__SiteContainer0
18. {
19. // FIElds
20. public static CallSite<Action<CallSite, object>> <>p__Site1;
21. }
22. }
06行先把賦值給dynamic的值賦給object類型,檢查編譯器 生成的靜態類<Main>o__SiteContainer0的靜態字段<>p__Site1是 否為null,如果是,則對其賦值,賦值的內容在這裡不詳細研究。然後調用 <>p__Site1進行操作。
這裡會發現兩個問題:賦值給dynamic的值 賦給object類型,對於值類型會不會執行同樣的操作,會執行裝箱操作嗎;編譯 器生成的靜態類<Main>o__SiteContainer0的靜態字段<>p__Site1 應該是緩存作用。這兩個問題稍後驗證。
1)對值類型進行的操作
如下代碼:
using System;
namespace Xianfen.Net.TestDynamic
{
class Program
{
static void Main()
{
dynamic d = 5;
d.ToString();
}
}
}
反編譯代碼:
internal class Program
{
// Methods
private static void Main()
{
object d = 5;
if (<Main>o__SiteContainer0.<>p__Site1 == null)
{
<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.
Create(new CSharpInvokeMemberBinder(CSharpCallFlags.None, "ToString", typeof(Program),
null, new CSharpArgumentInfo[] { new CSharpArgumentInfo (CSharpArgumentInfoFlags.None, null) }));
}
<Main>o__SiteContainer0.<>p__Site1.Target (<Main>o__SiteContainer0.<>p__Site1, d);
}
// Nested Types
[CompilerGenerated]
private static class <Main>o__SiteContainer0
{
// FIElds
public static CallSite<Action<CallSite, object>> <>p__Site1;
}
}
可見確實對值類型進行了裝箱操作,效率可想而知。