针对Anders Hejlsberg的一次采访

27 Feb 2014

1 Intro

A Conversation with Anders Hejlsberg 地址:http://www.artima.com/intv/choices.html

里面的内容提取了下,按照自己的理解写下来。C#不熟悉有些名词应该不标准。本意是看下第八部分,顺便扫了第七。

2 PART VII

2.1 泛型简介

[编译期或者是运行期前的动态类型。静态类型语言对动态类型的实现方式。]

2.2 C#的问题

C#的泛型类型按照普通情况进行编译。但是会记录下泛型的一些信息。等到运行的时候,如果需要,会检查是否存在制定类型,没有则组装成为指定类型。

对于值类型int,float,double,long等不同的类型会组成不同的代码,而不是上面的共享形式,以提高性能。引用类型是共享泛型代码的,但是不同的引用类型的泛型是不同的。

2.3 C#泛型与Java的区别

Java的目标是能够在不修改VM的前提下提供泛型支持。

  1. [其实本质只是将类型参数在编译器替换成Object类型]没有性能优势。
  2. 缺失了类型信息后,运行期很多操作就无法进行了。

C#的实现可以避免以上两点,因此运行期可以进行各种操作,组合出各种的泛型类型。

2.4 C#与C++

C#的泛型相对更接近面向对象的类型。C++的模板则更接近于宏。

  1. C++在编译期进行了类型参数的替换。C#在运行时才进行替换。
  2. C#进行比较严格的类型检查,这样在运行的时候不会出现类型错误[主要应该是接口不符合,因为类型的标志就是接口]。C++可能会因为类型接口不存在出现运行时的错误。

2.5 C#泛型的限制条件

C#可以制定泛型类型需要符合的条件[自然是接口,或者父类,其实也是接口的一种形式]

C++的限制条件可以认为是隐式的[也是上一问题第二点问题的原因],C#也可以隐式,但是会出现运行期的类型检查转换,而且会出现C++一样的运行时错误的情况。显式声明限制条件则可以避免开销和错误,在编译期就会直接无法通过编译。利用反射在运行期的操作则会出现Exception。

C#泛型限制条件可以支持限制一个类和多个接口[针对接口的匹配,或者说是针对方法的匹配]。但是不支持操作的制定,无法直接制定具有+操作,但是退一步可以制定一个具有+操作的类。

[后面有一个复杂限制的例子,但是不过是设计模式的技巧,不属于语法支持了]

3 PART VIII

主要的几个议题及其回应:

3.1 解释与优化

3.1.1 问题0

JVM的虚拟机的指令是区分类型的,IL的则不区分的原因。

  1. 回应

    对于虚拟机来说,区分类型可以提升效率。但是CRL本身的设计目的不是为了解释,其代码最后都是要编译的。而CRL中数据都是带类型标注的,所以IL上不考虑类型也没有增加复杂度,[因为无论如何都要检查类型然后编译到机器码与IL没有太多关系,而且数据本身也都有类型标注的]

3.1.2 问题1

CLR是否支持解释运行。JVM可以边解释边编译热点代码提高性能。

  1. 回应

    可以支持,但是不是主要目标,也不考虑这个方向的优化。因为JIT编译器已经可以避免这个问题。先弄一个快速编译的,然后发现热点代码后再将其用更优化的编译器编译。

3.1.3 问题2

non-virtual method在C#中是默认的,JVM则不同,默认不是final的。是因为性能问题,非final的方法是需要时间查找需要调用的方法的。JVM在运行中优化时可以内联正确的方法。

  1. 回应

    内联正确的方法也是需要之前跟踪调用情况的,这个也是要一些性能损耗的。

3.2 Unsafe代码

3.2.1 问题0

IL C#里面有支持指针操作的代码。为何如此设计?JVM都是必须使用JNI调用。

  1. 回应

    这些代码运行环境都是受控的,而且相比JNI来说,由于标准化在语言中,更加明确。如果写JNI,问题可能会更多点。

3.3 值类型

3.3.1 问题0

CRL中支持值类型,而Java中是区分基础类型和包裹的类型。如此设计是性能的考虑还是为了方便性?

  1. 回应

    主要是性能问题。完全的面向对象可以是不存在基础类型,完全都是包裹类(都是在堆中分配),但是性能开销是比较大的。 一般来说就是要么接受这种开销,要么向Java和C++这种,区分两种类型。但是这样写代码是比较麻烦的。值类型就是为了保证代码的一致性,在栈中性能与Java的基础类型无异。但是也可以在需要时从堆中分配。

3.4 不变类型

3.4.1 问题0

是否考虑支持?类似C++的const。

  1. 回应

    不变类型是从外部的角度来说的。而且编译器难以识别。[这里的是一种不变类型,类似于Java String]对于const,其实只是人们希望能够增加一个语法层面的限制。对于C++有const是因为其中可以比较随意的转换,如果增加一个语法上的严格限制,反而会不方便使用了。[这里是一种不变类型]