浅谈.NET编译时注入(C#-->IL)
2014-02-16 22:18
197 查看
.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:
反编译后的C#:
这里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#:
编译器为我们在这里生成了代理方法。
总结:
关于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;
}
}
}
反编译后:
今天就到此为至,只是简单的了解下IL注入实例,在后面会利用MSBuild
Task+Mono Cecil 和PostSharp实现一些简单的注入实例.
1:我们先来看看最简单的var:
C#:
public void TestVar()
{
var i = 0;
Console.WriteLine(i);
}
使用Reflector查看生成
IL:
反编译后的C#:
这里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#:
编译器为我们在这里生成了代理方法。
总结:
关于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;
}
}
}
反编译后:
今天就到此为至,只是简单的了解下IL注入实例,在后面会利用MSBuild
Task+Mono Cecil 和PostSharp实现一些简单的注入实例.
相关文章推荐
- 浅谈.NET编译时注入(C#-->IL)
- 浅谈.NET编译时注入(C#-->IL)
- 浅谈.NET编译时注入(C#-->IL) 推荐
- linux内核编译(2.4.20--->2.6.14)
- Android 编译命令 make j8 2>&1 | tee build.log 解释
- GCC编译过程 [ISO -> -ESc]
- 网站源文件被注入了<iframe>代码―ARP欺骗的木马病毒攻击
- Android系统移植与调试之------->MTK 标准编译命令
- <flex4.6 保留自动产生的actionscript代码的编译选项>
- 编译uboot-TI DM8186<<TI81XX PSP U-Boot>>
- (7) linux 编译并安装mysql-5.6.15.tar.gz ---> CentOS-6.6-x86_64 + mysql-5.6.15.tar.gz
- VC6.0编程用到#include <unistd.h>编译时出现的错误及解决方法
- ※开发工具※=>☆VS2005☆=>※№统一管理头文件路径和编译宏
- Linux -> usb-serial -> option.c 设备编译
- 小证明题 编译原理-->题目原型:
- VC->Project settings->C/C++编译参数的设置
- 使用muduo编译链接错误 undefined reference to `muduo::ThreadPool::run(boost::function<void ()()>&&)'
- <备忘1004>编译Windows版本的VLC软件
- 搭建fedora16->tiny210 Qt交叉编译环境 总结