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

简介:

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

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

C#:

 
  1. public void TestVar()  
  2.  
  3. {   
  4.    var i = 0;  
  5.    Console.WriteLine(i);  

使用Reflector查看生成

IL:

反编译后的C#:

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

2:Action<int>:

C#:

 
  1. public void TestAction()  
  2.  
  3. {  
  4.  
  5. var i = 1;  
  6.  
  7. Func<int,int> f = t => t+1;  
  8.  
  9. i=10;  
  10.  
  11. f(i);  
  12.  

反编译后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#:

 

 
  1. using System;  
  2.  
  3. using System.Collections.Generic;  
  4.  
  5. using System.Linq;  
  6.  
  7. using System.Text;  
  8.  
  9. namespace ConsoleApplication1  
  10.  
  11. {  
  12.  
  13. class Program  
  14.  
  15. {  
  16.  
  17. static void Main(string[] args)  
  18.  
  19. {  
  20.  
  21. new Program().TestPostSharp();  
  22.  
  23. }  
  24.  
  25. [ErrorHandler()]  
  26.  
  27. public void TestPostSharp()  
  28.  
  29. {  
  30.  
  31. throw new Exception("I will throw a exception!");  
  32.  
  33. }  
  34.  
  35. }  
  36.  
  37. [Serializable]  
  38.  
  39. public class ErrorHandlerAttribute : PostSharp.Laos.OnMethodBoundaryAspect  
  40.  
  41. {  
  42.  
  43. public override void OnException(PostSharp.Laos.MethodExecutionEventArgs eventArgs)  
  44.  
  45. {  
  46.  
  47. //do some AOP operation!  
  48.  
  49. Console.WriteLine(eventArgs.Method+":" +eventArgs.Exception.Message);  
  50.  
  51. eventArgs.FlowBehavior = PostSharp.Laos.FlowBehavior.Continue;  
  52.  
  53. }  
  54.  
  55. }  
  56.  

反编译后:

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







 本文转自 破狼 51CTO博客,原文链接:http://blog.51cto.com/whitewolfblog/835136,如需转载请自行联系原作者


相关文章
|
API
.net core工具组件系列之Autofac—— 第二篇:Autofac的3种依赖注入方式(构造函数注入、属性注入和方法注入),以及在过滤器里面实现依赖注入
本篇文章接前一篇,建议可以先看前篇文章,再看本文,会有更好的效果。前一篇跳转链接:https://www.cnblogs.com/weskynet/p/15046999.html
405 0
.net core工具组件系列之Autofac—— 第二篇:Autofac的3种依赖注入方式(构造函数注入、属性注入和方法注入),以及在过滤器里面实现依赖注入
|
存储 开发框架 自然语言处理
【.Net底层剖析】3.用IL来理解属性
【.Net底层剖析】3.用IL来理解属性
133 0
【.Net底层剖析】3.用IL来理解属性
【深入浅出.Net IL】1.一个For循环引发的IL
【深入浅出.Net IL】1.一个For循环引发的IL
109 0
【深入浅出.Net IL】1.一个For循环引发的IL
|
物联网 Linux KVM
X86模拟龙芯与编译.NET CoreCLR
X86模拟龙芯与编译.NET CoreCLR
359 0
X86模拟龙芯与编译.NET CoreCLR
|
容器 .NET 开发框架
.net core 注入中的三种模式:Singleton、Scoped 和 Transient
我们都知道在 Startup 的 ConfigureServices 可以注入我们想要的服务,那么在注入的时候有三种模式可以选择,那么我们在什么时候选择什么样的模式呢? 在讲注入模式之前,我觉得很有必要了解服务生存期的概念! 服务生存期:ASP.NET Core 提供了一个内置的服务容器 IServiceProvider 负责管理服务的生命周期,从被依赖注入容器创建开始(就是将服务注入到你要使用的类的构造函数中),然后框架负责创建依赖关系的实例,并在不再需要时对其进行处理(就是说等我们调用完服务时,容器会自己去对注入的服务进行释放)。
1805 0
|
开发工具 git
使用批处理(.bat)文件一键编译 .NET CORE 网站并发布至 IIS
向 IIS 发布网站的传统方式是:开发人员在开发机上对项目源代码编译并将生成的程序集复制到服务器上的网站目录中.在 .NET CORE 时代开启后,复制操作很容易因为文件占用而失败.
226 0
|
XML 监控 数据库
.net core 注入机制
本来是要先出注入机制再出 管道 的,哈哈哈……就是不按计划来…… 这里扯扯题外话:为什么要注入(DI,dependency-injection),而不用 new 对象? 可能我们都很清楚,new 对象所造成的影响就是耦合度太高,DI 就是用来解耦的。
1103 0