原文:浅谈.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:

反编译后的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 CecilPostSharp实现一些简单的注入实例.

浅谈.NET编译时注入(C#-->IL)的更多相关文章

  1. 浅谈C++编译原理 ------ C++编译器与链接器工作原理

    原文:https://blog.csdn.net/zyh821351004/article/details/46425823 第一篇:      首先是预编译,这一步可以粗略的认为只做了一件事情,那就 ...

  2. 转载--浅谈spring4泛型依赖注入

    转载自某SDN-4O4NotFound Spring 4.0版本中更新了很多新功能,其中比较重要的一个就是对带泛型的Bean进行依赖注入的支持.Spring4的这个改动使得代码可以利用泛型进行进一步的 ...

  3. 浅谈java编译机制和运行机制

    源文件和字节码的组成方式 源文件: 拓展名后跟java的文件即java的源文件. Java 源码编译由以下三个过程组成: 1.分析和输入到符号表 2.注解处理 3.语义分析和生成class文件 流程图 ...

  4. 浅谈 C# SQL防注入

    1#region 防止sql注入式攻击(可用于UI层控制)  2  3///   4/// 判断字符串中是否有SQL攻击代码  5///   6/// 传入用户提交数据  7/// true-安全:f ...

  5. 浅谈学习C++时用到的【封装继承多态】三个概念

    封装继承多态这三个概念不是C++特有的,而是所有OOP具有的特性. 由于C++语言支持这三个特性,所以学习C++时不可避免的要理解这些概念. 而在大部分C++教材中这些概念是作为铺垫,接下来就花大部分 ...

  6. 【Spring】浅谈spring推荐构造器注入

    一.前言 ​ Spring框架对Java开发的重要性不言而喻,其核心特性就是IOC(Inversion of Control, 控制反转)和AOP,平时使用最多的就是其中的IOC,我们通过将组件交由S ...

  7. 浅谈远程登录时,ssh的加密原理

    SSH:Secure Shell,是一种网络安全协议,主要用于登录远程计算机的加密过程. 登录方式主要有两种: 1.基于用户密码的登录方式:   加密原理:   当服务器知道用户请求登录时,服务器会把 ...

  8. 浅谈JVM编译原理->.java文件转变为.class文件的过程

    为什么需要编译? 我们平常写代码,有规范的命名方式,都能够看得懂,但是我们写的代码计算机是看不懂的,所以需要编译,也就是一个转换的过程,如下: 1.这个是咱们平时写的代码,就比较好理解,对人友好 2. ...

  9. 编译时MSIL注入--实践Mono Cecil(1)

    原文:编译时MSIL注入--实践Mono Cecil(1) 紧接上两篇浅谈.NET编译时注入(C#-->IL)和浅谈VS编译自定义编译任务—MSBuild Task(csproject),在第一 ...

随机推荐

  1. js进阶 10-8 伪类选择器有哪几类(自己不用,永远不是自己的)

    js进阶 10-8 伪类选择器有哪几类(自己不用,永远不是自己的) 一.总结 一句话总结:自己不用,永远不是自己的. 0.学而不用,却是为何? 自己不用,永远不是自己的,有需求的时候要想到它,然后操作 ...

  2. TensorFlow中卷积

    CNN中的卷积核及TensorFlow中卷积的各种实现 声明: 1. 我和每一个应该看这篇博文的人一样,都是初学者,都是小菜鸟,我发布博文只是希望加深学习印象并与大家讨论. 2. 我不确定的地方用了“ ...

  3. python 多线程拷贝单个文件

    # -*- coding: utf-8 -*- # @author: Tele # @Time : 2019/04/04 下午 12:25 # 多线程方式拷贝单个文件 import threading ...

  4. 常见的面试C#技术题目

    遍历查询窗体界面的textbox为空值 ? foreach (System.Windows.Forms.Control control in this.Controls)            {   ...

  5. ServletContextListener接口用法

    ServletContextListener接口用于tomcat启动时自动加载函数,方法如下: 一.需加载的类必须实现ServletContextListener接口. 二.该接口中有两个方法必须实现 ...

  6. 收集 天创恒达高清采集卡TC-5A0N7

    版权声明:本文博客琅邪工作室原创文章,博客,未经同意不得转载.

  7. Python 标准库 —— uuid(生成唯一 ID)

    有时我们在百度贴吧,在一个网站,保存网页上的一些图片时,图片名有时会是一串很长的数字和字母组成的,但无一例外,图像之间不会出现重名.这个唯一的 id,一般通过 uuid 的方式获得,uuid 根据的是 ...

  8. WPF 获得触摸精度和触摸点

    原文:WPF 获得触摸精度和触摸点 本文主要告诉大家如何获得所有的触摸设备的触摸精度和触摸点数. 需要通过反射的方法才可以拿到触摸的精度. 使用 Tablet.TabletDevices 可以获得所有 ...

  9. CUDA—使用GPU暴力破解密码

    GPU支持大规模的并行加速运算,胜在量上,CPU处理大量的并行运算显得力不从心,它是胜在逻辑上.利用显卡加速的应用越来越多,但如果说GPU即将或最终将替代CPU还有点言过其实,二者最终将优势互补,各尽 ...

  10. android module 模块共用远程包

    在项目有多模块,需要使用到同一个第三方包时,引入报错,个人解决方法如下 1. 在模块build.gradle 文件中配置maven远程地址 可从app下的build.gradle文件里复制 allpr ...