zoukankan      html  css  js  c++  java
  • 为什么在VS2010中编写.net 2.0程序可以调用C#2.0以上版本特性?

    公司的程序一般使用会使用.Net 2.0,在使用VS2010编写程序后,发现使用了一些C#3.0,C#4.0特性后,程序居然也可以正常运行,对此一直有点迷惑,最近花了点时间仔细研究了一下。

    在讨论为什么VS2010会出现这种情况之前,先引入几个概念,我们重新认识一下。

    201206171833245048

    C#版本与C#编译器

    C#源代码要编译成IL中间语言,需要调用C#编译器。C#编译器其实是一个名为csc.exe的可执行文件,通常位于系统目录下的 Microsoft.NET\Framework\<version> 文件夹中,version指的是.Net的版本,我的电脑中装有VS2005 VS2008 VS2010时,里面有v1.0 、v1.1 、v2.0、 v3.0、 v3.5、 v4.0几个版本。经过查看,我发现v2.0 、v3.5、 v4.0里面含有csc.exe文件,而这正好和C#的版本是对应的。不难想到,不同版本C#编译器代表编译过程中遵循不同C#版本的语法

    现在回到我们的问题:VS2010中.Net2.0工程可以使用C#2.0版本以上的特性。初步可以怀疑VS2010编译时调用的是4.0版本的C#编译器,而不是2.0版本的C#编译器。

    下面实际编译一段代码来试验一下。这段代码在VS2010生成是可以通过的。

    class Program
        {
            static void Main(string[] args)
            {
                ///隐式类型变量 (C#3.0特性)
                  var i = 0;
                Console.WriteLine(i.ToString());
                Console.ReadKey();
            }
        }

    使用2.0的C#编译器,编译失败

    image

    使用4.0的C#编译器,编译成功

    image

    VS2010直接生成得到的ConsoleApplication2.exe,我使用C#编译器自己生成的是Test.exe文件。现在,我发现两个文件有一点不相同。他们引用的mscorlib.dll版本不同。

    imageimage

    其实,在设置项目工程的.Net Framework版本时,就是设置C#编译器编译时调用对应版本的mscorlib.dll文件。(mscorlib.dll到底代表什么,可以查阅CTS BFL等概念)

    虽然现在两个exe文件中的引用不同,但是我们可以手工调用对应版本的mscorlib.dll文件,重新生成一个exe文件。(/nostdlib 禁止导入定义整个 System 命名空间的 mscorlib.dll,也就是4.0的mscorlib.dll)

    imageimage

    通过以上实验,可以说明VS2010调用了4.0版本的C#编译器。

    C#特性的实现

    VS2010调用了4.0版本的C#编译器成功编译了.Net 2.0工程的源代码,说明C#源代码成功编译成IL中间语言代码。但是C#2.0版本以上的特征为什么可以成功编译,还没有明白。

    C#是高级语言,IL是相对C#低级一些。C#特性在实现上要依赖IL特性。在此我能想到的C#特性的实现有两种(关于什么才能称为特性,我暂且认为这个版本新增的就为这个版本的特性):

    1. 直接是IL特性的实现。比如private 关键字,可以适应Reflector查看IL代码,里面就有private关键字。这种实现方式不需要调用其他的资源如dll程序集。
    2. 结合或者直接就是.Net 版本的另一种实现方式,需要依靠mscorlib.dll或者其他程序集。比如lock关键字,封装了Monitor线程处理方法,是一种语法糖。这种特性,没有相应的dll是不能调用的。

    那么由此C#2.0以上版本的特性,如果属于第一种情况,那么Net2.0工程中使用是没有问题的。如果属于第二种情况,那么需要mscorlib.dll为2.0版本,.Net2.0工程才可以能使用。

    经过实验总结:以下特性是可以使用的

    1. 对象初始化器
    2. 集合初始化器
    3. 自动属性
    4. 隐式类型变量
    5. 隐式类型数组
    6. 匿名类型
    7. lamda表达式
    8. 可选参数(4.0):其实.Net 2.0版本中 VB语言就实现了可续参数。

    总结

    有高版本的C#编译器,就可以使用C#高版本的特性。能用的特性尽情的用,不能用的特性会报错误,自然也就无法用了。

    为什么在VS2010中编写.net 2.0程序可以调用C#2.0以上版本特性?其实从这个问题中,便可以发现我将.Net版本与C#版本的概念混淆了。这句话应该这样,在VS2010开发环境下,使用的是4.0版本的C#编译器,如果创建.Net 2.0项目,可以使用C#4.0中任何不依赖.Net和仅依赖于.Net 2.0的C#特性

     

    本文写的十分浅薄,请结合一下两篇文章阅读,会更清楚一些。

    http://www.cnblogs.com/JimmyZhang/archive/2012/11/27/2790759.html

    http://www.cnblogs.com/PurpleCow/archive/2012/06/17/2552780.html

  • 相关阅读:
    Objects类源码详解(基于jdk1.8.0_261)
    Object类源码详解(基于jdk1.8.0_261)
    Collections工具类源码详解(基于jdk1.8.0_261)
    版本控制神器——git的基本使用
    数据结构练习1~插入排序~
    求指错啊急是求幂的
    编完了个代码大家给看看还能不能精简
    关于KMP算法
    有网友建议写一个新手指南或者FAQ一类的置顶你们认为呢
    c语言新手编程错误求解
  • 原文地址:https://www.cnblogs.com/desmond/p/3002997.html
Copyright © 2011-2022 走看看