浅谈.NET编译时注入(C#-->IL)

简介:

   .NET是一门多语言平台,这是我们所众所周知的,其实现原理在于因为了MSIL(微软中间语言)的一种代码指令平台。所以.NET语言的编译就分为了两部分,从语言到MSIL的编译(我喜欢称为预编译),和运行时的从MSIL到本地指令,即时编译(JIT)。JIT编译分为经济编译器和普通编译器,在这里就不多说了,不是本文的重点。本文主要讨论下预编译过程中我们能做的改变编译情况,改变生成的IL,从编译前后看看微软C#3.0一些语法糖,PostSharp的静态注入等等。

1:我们先来看看最简单的var:

C#:

复制代码
public   void  TestVar()

   var i  =   0 ;
   Console.WriteLine(i);
}
复制代码

使用Reflector查看生成

IL:

clip_image001

反编译后的C#:

clip_image002

这里VS在编译的时候将var为我们转变为了int类型。

2:Action<int>:

C#:

复制代码
public   void  TestAction()

{

var i 
=   1 ;

Func
< int , int >  f  =  t  =>  t + 1 ;

i
= 10 ;

f(i);

}
复制代码

反编译后C#:

clip_image004

clip_image005

编译器为我们在这里生成了代理方法。

总结:

关于lambda表达式的编译规则:

当一个lambda expression被赋值给一个delegate类型,例如Action<T>或者Func<T, TResult>等,这个lambda expression会被编译器直接编译为 
1) 当lambda expression没有使用闭包内的非局部引用也没有使用到this时,编译为一个私有静态方法; 
2) 当lambda expression没有使用闭包内的非局部引用,但用到了this时,编译为一个私有成员方法; 
3) 当lambda expression中引用到非局部变量,则编译为一个私有的内部类,将引用到的非局部变量提升为内部类的。

3:PostSharp:

PostSharp是结合了 MSBuild Task 和 MSIL Injection 技术,编译时静态注入实现 AOP 编程。在编译时候改变VS的编译行为。更详细的信息,请访问 PostSharp 网站

原c#:

复制代码
using  System;

using  System.Collections.Generic;

using  System.Linq;

using  System.Text;

namespace  ConsoleApplication1

{

class  Program

{

static   void  Main( string [] args)

{

new  Program().TestPostSharp();

}

[ErrorHandler()]

public   void  TestPostSharp()

{

throw   new  Exception( " I will throw a exception! " );

}

}

[Serializable]

public   class  ErrorHandlerAttribute : PostSharp.Laos.OnMethodBoundaryAspect

{

public   override   void  OnException(PostSharp.Laos.MethodExecutionEventArgs eventArgs)

{

// do some AOP operation!

Console.WriteLine(eventArgs.Method
+ " : "   + eventArgs.Exception.Message);

eventArgs.FlowBehavior 
=  PostSharp.Laos.FlowBehavior.Continue;

}

}

}
复制代码

反编译后:

clip_image007

今天就到此为至,只是简单的了解下IL注入实例,在后面会利用MSBuild Task+Mono Cecil 和PostSharp实现一些简单的注入实例.


本文转自破狼博客园博客,原文链接:http://www.cnblogs.com/whitewolf/archive/2011/07/26/2117661.html,如需转载请自行联系原作者

目录
相关文章
|
.NET C# C++
详解.NET IL代码(一)
  本文主要介绍IL代码,内容大部分来自网上,进行整理合并的。 一、IL简介  为什么要了解IL代码?   如果想学好.NET,IL是必须的基础,IL代码是.NET运行的基础,当我们对运行结果有异议的时候,可以通过IL代码透过表面看本质;IL也是更好理解、认识CLR的基础;大量的实例分析是以IL为基础的,所以了解IL,是读懂他人代码的必备基础,同时自己也可以获得潜移默化的提高;  什么是IL?   IL是.NET框架中中间语言(Intermediate Language)的缩写。
2240 0
|
存储 开发框架 自然语言处理
【.Net底层剖析】3.用IL来理解属性
【.Net底层剖析】3.用IL来理解属性
149 0
【.Net底层剖析】3.用IL来理解属性
|
Windows
如何通过ildas“.NET技术”m/ilasm修改assembly的IL代码
  这段时间为跟踪一个Bug而焦头烂额,最后发现是Framework的问题,这让人多少有些绝望。所以到微软论坛提了个帖子,希望能得到些帮助。虽然论坛智能到能够判断楼主是否是MSDN订阅用户,以便尽快解决(传说MSDN订阅用户的问题能在两天内得到回复的,当时还很得意公司为我们购买的MSDN订阅账号),但得到的回复是“Could you file a bug report for this issue through Connect?”,绝望之后的又一次寒心啊。
1015 0
|
Windows
一起谈.NET技术,如何通过ildasm/ilasm修改assembly的IL代码
  这段时间为跟踪一个Bug而焦头烂额,最后发现是Framework的问题,这让人多少有些绝望。所以到微软论坛提了个帖子,希望能得到些帮助。虽然论坛智能到能够判断楼主是否是MSDN订阅用户,以便尽快解决(传说MSDN订阅用户的问题能在两天内得到回复的,当时还很得意公司为我们购买的MSDN订阅账号),但得到的回复是“Could you file a bug report for this issue through Connect?”,绝望之后的又一次寒心啊。
989 0
|
Windows
如何通过ildasm/ilasm修改assem“.NET研究”bly的IL代码
  这段时间为跟踪一个Bug而焦头烂额,最后发现是Framework的问题,这让人多少有些绝望。所以到微软论坛提了个帖子,希望能得到些帮助。虽然论坛智能到能够判断楼主是否是MSDN订阅用户,以便尽快解决(传说MSDN订阅用户的问题能在两天内得到回复的,当时还很得意公司为我们购买的MSDN订阅账号),但得到的回复是“Could you file a bug report for this issue through Connect?”,绝望之后的又一次寒心啊。
1173 0
|
.NET Windows
理解.NET程序集的执行过程
  对于一个已编译好的.NET程序集,Windows操作系统是如何启动执行的呢?日常使用中我们发现对于托管的和非托管的程序集编译器都会吧程序集编译成以.exe或.dll等为扩展名的文件,可见Windows加载器并没有区分是托管还是非托管的程序集,而且我们也知道对非托管的程序集是在编译器直接编译成了机器码,自然可以由CPU直接执行,而托管的.
773 0
|
Windows
一起谈.NET技术,.NET动态调用DLL的方法
  很多软件都是可插拔的,最知名的便是微软的Windows操作系统。你可以在Windows操作系统上安装QQ,也可卸掉QQ,这便是可插拔。这里不谈Windows的实现,因为太过复杂。本文就谈谈管理软件的可插拔的实现。
1480 0
|
程序员 C#
一起谈.NET技术,写出优雅简明代码的论题集 -- Csharp(C#)篇[1]
  最近和一些朋友讨论如何写出优雅的代码,我们都很喜欢C#,所以以C#为例。主要一共有三位程序员在一起讨论,为简单起见我用ABC代表我们三个人。   有时候我们会针对一些代码进行讨论,有时候我们会提出一些观点,有时候我们会一起学习网上一些现有的博客,为了便于大家引用,我给每一个论题都编上号。
1088 0
|
程序员 C#
一起谈.NET技术,写出优雅简明代码的论题集 -- Csharp(C#)篇[2]
  谢谢大家对本系列第一篇写出优雅简明代码的论题集 -- Csharp(C#)篇[1]的回复和讨论,我相信针锋相对的辩论不仅有助于发现答案,更让我们了解问题后面的实质。   对程序员而言,我们的代码需要:   1. 在预算内实现需求,让用户可以使用 -- 让自己或者公司可以赚到钱   2. 方便自己修改及日后维护   3. 方便别人修改及日后维护   4. 便于重复使用,为以后的开发节省时间   5. 让系统高效的运作   从美国商学院毕业的学生们掌握了很多相似的思维模式,这不仅有利于他们解决问题,更重要的是方便他们彼此之间沟通。
1007 0
|
.NET Windows
一起谈.NET技术,理解.NET程序集的执行过程
  对于一个已编译好的.NET程序集,Windows操作系统是如何启动执行的呢?日常使用中我们发现对于托管的和非托管的程序集编译器都会吧程序集编译成以.exe或.dll等为扩展名的文件,可见Windows加载器并没有区分是托管还是非托管的程序集,而且我们也知道对非托管的程序集是在编译器直接编译成了机器码,自然可以由CPU直接执行,而托管的.
722 0