CLR 2.0和CLR 4.0的区别

22

我已经阅读了许多关于C# 4.0新特性的博客、帖子和StackOverflow问题。甚至WPF 4.0的新功能也已经开始公开。我找不到并想知道的是:

  1. 从C#/WPF开发人员的角度来看,CLR 4.0有哪些重大变化?
  2. 整个CLR 4.0有哪些重大变化?

我认为,在内部,大多数更改��是针对新的动态语言和并行编程。但是还有其他主要的改进吗?因为语言的改进只是语言的改进。你只需要新的编译器,这些功能就可以与较低版本的 .Net 一起使用,除了1.0/1.1版本(至少大多数功能可以使用)。

如果以上功能是唯一的功能,那么版本之所以更改为4.0,只是因为它基于 .Net 4.0 版本,即在1.0/1.1、2.0和3.0/3.5之后的版本。版本增加是否合理?

编辑:

正如Pavel Minaev在评论中指出的那样,即使这两个功能与CLR无关。在3.0和3.5中也有速度和其他改进。那么版本增加的原因是什么呢?


1
CLR 直接不支持动态语言和并行编程。动态语言由 DLR 支持,它是建立在 CLR 之上的(不使用任何特定于 CLR 的内容,并且可以在 2.0 上运行得很好)。Parallel FX 只是一个库。 - Pavel Minaev
7个回答

11
我知道的一个新的CLR功能是一种结构化接口、结构体和委托类型的类型化形式,用于支持NoPIA support,基本上,它使运行时将具有等效定义的不同类型视为相同类型——因此,如果两个程序集AB中都声明了一个名为IFoo的COM导入接口,具有相同的IID和相同的成员,则运行时将把它们视为等效类型;因此,如果有一个实现了[A]IFoo的类Foo的实例,你可以将其转换为[B]IFoo,转换将起作用。
另外一个功能是能够在单个进程中并排承载多个CLR版本。例如,你不能在一个进程中承载1.x和2.0,但可以承载2.0和4.0。这样做的主要好处是能够同时加载针对任一CLR版本编写的插件。
还有一个小问题是一些异常已经变得无法捕获,就像在2.0中的StackOverflowException一样——例如,你不能再捕获AccessViolationException
此外,here是来自PDC 2008的关于CLR 4.0的PowerPoint演示文稿。现在可能有点过时了,但那里提到的大部分东西似乎都在beta版中。

@Pavel,为什么你在4中不能再捕获那些异常了?它们已经过时了吗? - Joan Venge
它们被故意设置为无法捕获,因为没有合法的理由让应用程序捕获它们。对于 StackOverflowException,这是因为任何错误处理代码都无法做太多事情的条件(如果你已经超出了堆栈,甚至无法进行方法调用...)。对于 AccessViolationException,这是因为它本质上是不确定性的 - 会导致其发生的操作也可能读取(或更糟的是,写入)一些不相关的内存区域;因此捕获它总是一个设计问题。 - Pavel Minaev
2
“AccessViolationException” 可能变得无法捕获,因为代码访问安全已被弃用,这导致该异常已经不再使用:http://www.infoq.com/news/2010/01/CAS-.NET-4.0。它从来没有是不确定的,特别是在您想要允许运行外部代码的领域中。” - Abel
3
AccessViolationException 与代码访问安全性完全无关(特别是当您的代码违反CAS规则时,不会抛出此异常)。它只是 Windows 中分段错误的说法(参见 http://en.wikipedia.org/wiki/Access_violation)。 - Pavel Minaev

4

有大量的变化。

在CLR本身中,有一些变化。垃圾回收器正在改变以支持工作站模式下gen0/1和gen2的并发收集。此外,安全性的实现方式也有所改变。并行框架改变了CLR线程池的一些实现(它并不完全是托管的,而是部分运行时本身)。此外,类型系统也有一些变化,主要与新的PIA COM支持有关。

最大的变化可能更多地是库/框架的变化,而不是CLR的变化。例如将DLR集成到框架中和新的动态类型。在框架方面,你有反应框架、并行库扩展、代码约束、元组支持以及许多小的变化(例如Enum.TryParseLazy<T>和许多其他小而美好的改进)。


3
“dynamic” 是 C# 中的一个关键字,它不是 CLR(公共语言运行库)类型。至于你所说的“将 DLR 集成到 CLR 中”,能否解释一下?实际上,DLR 只是一个库而已。 - Pavel Minaev
已编辑。尽管其中一些需要特定的更改。 - Reed Copsey

2
我不相信有任何新的IL指令。新的CLR在内联和垃圾回收等方面有所改进,完成与2.0 CLR相同的工作,但更好。虚拟机(如CLR或JVM)是一个抽象概念,有多种可能的实现。我相信CLR 4.0与CLR 2.0中的抽象机器相同,只是实现得更好。

即使是新的动态内容也只是编译器技巧,带有新的API(不像Java中提出了一种新的操作码。)

如果我对此错误,请告诉我!


必须有一个 (107),反射器一直抛出异常 :) - leppie

2


1

为了支持泛型协变和逆变性,CLR中的许多核心接口和委托类型已经更新。例如,IEnumerable<T>已更改为IEnumerable<out T>


1
那不是CLR(公共语言运行时),那是BCL(基类库)。CLR是虚拟机。 - Pavel Minaev
很好。对公共接口的更改是BCL更新,以利用CLR中的新功能。 - Joel Mueller
1
.NET 2.0 中添加了通用的协变性和逆变性,并且自此以后,支持它们的语言(例如 Eiffel.NET)一直可用。这不是 VES 或 CLR 中的新功能,而是纯粹的 C# 功能。如果 BCL 是用 Eiffel 而不是 C# 编写的,那么这些方差注释早在多年前就可以添加了。(实际上,它们可以通过字节码后处理步骤之类的方式来添加。) - Jörg W Mittag

0

我尝试使用Reflector查看一些新的C#内容,看看是否有什么新的东西:

  • dynamic类型通过编译器魔法转换为object,添加库调用以处理运行时绑定。
  • 可选参数通过编译器处理。如果您调用Foo(int x = 5),而没有为x指定值,则在Reflector中将看到该调用为Foo(5)。

所以我想这些变化并不是很容易发现的(就像CLR 2.0中的泛型支持一样)。


1
我没有尝试过动态类型,但可选参数在甚至 .Net 2.0 中都可以正常工作。你唯一需要的是 VS2010 C# 编译器。也许动态类型也可以工作,不过我不确定。 - Yogesh
不行,dynamic需要DLR以及C#绑定器,这些只有在4.0中的Microsoft.CSharp中才有。 - Pavel Minaev
2
程序集只支持.NET 4.0,但仅限于此。您只需要编译器、程序集,理论上应该能在CLR 2.0上运行。 - Doron Yaacoby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接