net 反编译 dynamic类型

看了很多人讨论Dynamic。不禁自己也想挖掘下。下面把自己的体会分享给大家

 

1.Dynamic关键字是为了方便访问某个对象。而跟DLR没太大关系。

使用了dynamic关键字创建的对象实际上是一个object. 使用.net 4.0以下的Reflector就可以看到.

使用dynamic关键字后编译器将会将这个对象后面的PropertyName翻译成相应Binder调用。因此语法检查器会忽略检查此对象是否包含PropertyName.

真正的跟DLR有关的是在System.Dynamic下的类型。

大家可以实验一个叫ExpandoObject的东西

1
2
3
4
5
6
7
8
private static void Main(string[] args)
{
    dynamic expandoObject = new ExpandoObject(); expandoObject.
    PropertyA = "PropertyA";
    expandoObject.PropertyB = 2010;
    Console.WriteLine(expandoObject.PropertyA);
    Console.WriteLine(expandoObject.PropertyB);
}


这个时候用d, , ynamic是不是有点动态语言的感觉了?所以说 dynamic不是DLR的实现,
但要用DLR在C#里最好的途径可能就是使用dynimic了。


 

2.Dynamic关键字是一个编译器做的语法糖

  

请看如下代码:

原始代码

 
<blockquote><pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;">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; }
    }</pre></blockquote>



用3.5语法反编译的
其实上面也都说的很清楚了 编译器会把dynamic编译在一个和dynamic所在函数名有关的Static SiteContainer

<Method1>o__SiteContainer0
<Method2>o__SiteContainer2 …等

 

而且是一个dynamic生成一个Site .装在对应的Container中。

下面我们来看Method1 反编译后

  
1
2
3
4
5
6
7
8
9
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反编译后

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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.<br><br>再看Method3和Method4
1
  

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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。眼看要下班了。笔先收一下,有时间再写:-)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Red-Gate Reflector 7.6.0.233 VS Pro Edition Pre-cracked by HF-Death / InFiNiTy-Team Debug any .NET assembly in Visual Studio : Enable debugging for 3rd party assemblies Quickly select assemblies to debug within Visual Studio. .NET Reflector generates PDB files for decompiled assemblies, so you can debug them as easily as your own code. Debug decompiled assemblies using the Visual Studio debugger Now you can step through debugging of any decompiled assemblies as if they were your own. Set breakpoints, watch variables, set next statements, modify variable values, or use any of your other regular debugging techniques. Decompile and explore assemblies on the fly: Dynamic decompilation With Reflector VSPro, assemblies decompile seamlessly in Visual Studio. So source code is always available for your libraries, and you can go straight to the definition of any code, either from the context menu, or by hitting F12 Browse decompiled assemblies .NET Reflector VSPro adds the Reflector Object Browser into Visual Studio. Use the simple tree view to navigate through all types and members, and click to see the decompiled code. A 2-Minute Demo of .NET Reflector VSPro Debug any .NET assembly in Visual Studio: Enable debugging for 3rd party assemblies Quickly select assemblies to debug within Visual Studio. .NET Reflector generates PDB files for decompiled assemblies, so you can debug them as easily as your own code. Select assemblies to decompile and debugSelect assemblies to debug The PDB files are saved for future use, so you only need to enable debugging onc for each assembly. Debug decompiled assemblies using the Visual Studio debugger Now you can step through debugging of any decompiled assemblies as if they were your own. Set breakpoints, watch variables, set next statements, modify variable values, or use any of your other regular debugging techniques. Debug decompiled assemblies using the Visual Studio debuggerDebug decompiled assemblies using the Visual Studio debugger Decompile and explore assemblies on the fly: Dynamic decompilation With Reflector VSPro, assemblies decompile seamlessly in Visual Studio. So source code is always available for your libraries, and you can go straight to the definition of any code, either from the context menu, or by hitting F12 Decompile any referenced assemblyDecompile any referenced assembly Browse decompiled assemblies .NET Reflector VSPro adds the Reflector Object Browser into Visual Studio. Use the simple tree view to navigate through all types and members, and click to see the decompiled code. Browse decompiled assembliesBrowse decompiled assemblies Back to top The world’s most advanced .NET decompiler: .NET Reflector VS can decompile any .NET assembly to C#, VB.NET or IL. .NET Reflector VS will decompile to high level C# features such as Iterator blocks, Lambda expressions, and LINQ queries. .NET Reflector also supports the C# 4 dynamic type. DotNET Reflector 7.5 Changes: * Many string changes to make things easier to understand * Assorted design changes to dialogs and screens * Improvements to the installation experience of the package * Improved the speed of type by type decompilation * Improved handling of the case where the add-in is superseded by the package (we remove the old menu items) * Error reporting experience is more fine-tuned. Users have options to be notified of work-arounds and fixes * Hide menu items such as “enable debugging”, instead of just disabling them * Make “enable debugging” work on all items of the tree, rather than just the top level assembly item * "Go to decompiled definition" more commonly enabled. * Setting a break point causes the necessary PDB file to be automatically generated * Decompiled code can now be stepped-into like any other code * Attempting to step into inaccessible code triggers instructions on how to debug it correctly * Multiple PDBs can now be generated in parallel o PDB generation can currently take a little time, especially if you’re generating several or the assemblies are particularly large * The trial dialog screen has been updated to be more informative and clear * Re-introduced “Go to Decompiled Definition” right-click menu item * Improved support for ‘Go to Definition’(F12) in code without source * A number of simple usability enhancements * A number of licensing and installation bug fixes * Added support for ‘Go to Definition’(F12) in code without source * Improved path to decompiled code * Improved path to pdb generation for code you want to debug * Completed move to a VS Package * Started transition from a VS Add-in to a VS Package * Added support for VS11 * Turned on SmartAssembly feature usage reporting on by default for all EA builds * Added loaded project references to the Reflector Object Browser (ROB) * Double click on any type in the ‘ROB’ to decompile in a new VS editor pane * Added a Reflector ‘Go to Definition’ context menu item to navigate through code without source * Added a new ‘Reflector Object Browser’(ROB) into Visual Studio (will eventually offer decompilation by type inside VS) * Changed the way Reflector shows the version number to display the correct build number * Bug fixes: o “Open in Reflector” context menu not working. o XAML Source Code is wrong delimited. o Missing end tag in XAML Translation. o Code generation for different versions of the same assembly o ‘Flatten Namespaces’ dialog o Various decompilation and assembly-loading problems have been fixed – drop us a note if you’d like to know more. DotNET Reflector 7.6.0.233 VS Pro Edition Cracked HF-Death / InFiNiTy-Team

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值