浅谈.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,如需转载请自行联系原作者

目录
相关文章
|
存储 Linux API
.NET Core获取程序运行行环境信息与反射的应用
.NET Core获取程序运行行环境信息与反射的应用
356 0
.NET Core获取程序运行行环境信息与反射的应用
|
算法 前端开发 网络安全
【Example】C++ 用于编译时封装的 Pimpl 演示 (编译防火墙 Private-IMPL)
什么是 Private-IMPL ? 即【隐藏实现的方式】,如果你还停留在学习的阶段,那这种方式对你的代码几乎毫无用处。 但是如果你走入到真实项目当中,这种方式又显得尤为重要。
150 0
|
.NET C# C++
详解.NET IL代码(一)
  本文主要介绍IL代码,内容大部分来自网上,进行整理合并的。 一、IL简介  为什么要了解IL代码?   如果想学好.NET,IL是必须的基础,IL代码是.NET运行的基础,当我们对运行结果有异议的时候,可以通过IL代码透过表面看本质;IL也是更好理解、认识CLR的基础;大量的实例分析是以IL为基础的,所以了解IL,是读懂他人代码的必备基础,同时自己也可以获得潜移默化的提高;  什么是IL?   IL是.NET框架中中间语言(Intermediate Language)的缩写。
2089 0
|
Windows
如何通过ildas“.NET技术”m/ilasm修改assembly的IL代码
  这段时间为跟踪一个Bug而焦头烂额,最后发现是Framework的问题,这让人多少有些绝望。所以到微软论坛提了个帖子,希望能得到些帮助。虽然论坛智能到能够判断楼主是否是MSDN订阅用户,以便尽快解决(传说MSDN订阅用户的问题能在两天内得到回复的,当时还很得意公司为我们购买的MSDN订阅账号),但得到的回复是“Could you file a bug report for this issue through Connect?”,绝望之后的又一次寒心啊。
977 0
|
Windows
一起谈.NET技术,如何通过ildasm/ilasm修改assembly的IL代码
  这段时间为跟踪一个Bug而焦头烂额,最后发现是Framework的问题,这让人多少有些绝望。所以到微软论坛提了个帖子,希望能得到些帮助。虽然论坛智能到能够判断楼主是否是MSDN订阅用户,以便尽快解决(传说MSDN订阅用户的问题能在两天内得到回复的,当时还很得意公司为我们购买的MSDN订阅账号),但得到的回复是“Could you file a bug report for this issue through Connect?”,绝望之后的又一次寒心啊。
965 0
|
缓存
详解.NET程序集的加载规则
  程序集的加载涉及到很多方面的知识,包括配置文件、全局缓存装配、私有目录等的查找。用LoadAWithPartialName方法加载程序集,必须提供程序集的文本名称,还可以包公钥标记、版本或区域性等,但不必包含完全引用信息,如名称、版本、区域性、公钥标记。
812 0
|
API C++ iOS开发
.net Core 2.1.x EntityFramework | 无法找到DatabaseGeneratedAttribute注释
.net Core 2.1.x EntityFramework | 无法找到DatabaseGeneratedAttribute注释 1向下投票最喜爱的   我正在尝试为我的应用程序使用.Net Entity Framework Core。
1651 0
|
C++ 开发工具 API
.NET Core工程编译事件$(TargetDir)变量为空引发的思考
前言 最近客户反馈,为啥不用xcopy命令代替我自己写的命令来完成插件编译复制: 我的: call "$(SolutionDir)tools\tools\Magicodes.CmdTools.
1314 0