C# 4.0的变化清单中有哪些适用于.NET 3.5?

23

最近我看到了很多关于C# 4.0的变化,有些我非常喜欢。但是因为兼容性原因,我还不想立刻转移到.NET 4.0上。

那么,是否有一个全面的新C# 4.0语言特性列表,可以在.NET 3.5或更低版本上工作?

以默认参数为例,它们需要.NET 4.0 CLR吗,还是只是编译器特性?可以使用自动属性(C# 3.0特性)并仍然针对.NET 2.0,因为那不需要Framework支持,但不能使用LINQ表达式,因为那需要Framework 3.5。

请不要说“当然C#4.0不能在.NET 3.5上工作,因为它更旧”。


3
我不确定是否存在这样的情况,因为.NET 4.0带来了新版本的CLR。您不能在2.0 CLR中运行.NET 4程序集(.NET 3.5使用的是2.0 CLR)。据我所知,C# 4编译器没有提供针对3.5的目标选项。 - Matt Greer
3
举个例子,缺省参数是需要.NET 4.0 CLR还是编译器特性?使用自动属性(C# 3.0特性)仍然可以针对.NET 2.0进行编译,因为这不需要框架支持,但不能使用LINQ表达式,因为它需要Framework 3.5的支持。 - John Saunders
1
@Earlz:实际上,你仍然可以使用LINQ查询表达式。它们是一种语法特性。你错过的是LINQ-to-objects、LINQ-to-XML和其他相关功能。看看LinqBridge吧。 - R. Martinho Fernandes
例如,在.NET 2.0中可以使用LINQ,因为它在编译时完成,并且2.0和3.5都针对相同的CLR。但是由于4针对新的CLR,我怀疑是否有任何内容可以转移。是的,4编译器可以针对3.5,但那只是像3.5编译器一样。 - Matt Greer
1
@Matt:这可能是事实,但CLR的新不强制禁止使用仅来自编译器的功能,就像您可以使用自动属性并针对.NET 1.1进行目标设置一样。 - R. Martinho Fernandes
显示剩余2条评论
5个回答

31

在4.0版本中,C#编译器增加了一个新的多目标功能。简单来说,它会生成一个程序集,其元数据版本与定义System.Object的引用中存在的版本相同(通常是mscorlib.dll)。这使得你可以使用它来编译2.0和3.5的程序集,以及各种版本的Silverlight。这个功能是为了支持Visual Studio 2010中的多目标而引入的。

因此,您可以使用C# 4.0编译器编译3.5程序集,并利用任何您想要的C# 4功能,只要没有特定于4.0库的依赖项即可。例如,命名参数和可选参数将正常工作,因为它们不使用任何4.0框架功能。然而,动态特性确实需要,因此默认情况下它将无法在3.5上工作。

这里有一篇帖子涵盖了基础知识。

http://blogs.msdn.com/ed_maurer/archive/2010/03/31/multi-targeting-and-the-c-and-vb-compilers.aspx

下面是Ed's post中的简短列表:

  • 命名参数和可选参数
  • 某些COM语法改进(例如“省略ref”)
  • 泛型方差

不能工作的包括dynamic和no-pia(我们在实现它们方面所花费的时间最多的两个因素)。前者需要框架支持,后者需要运行时支持。


很好的答案,但我想知道的是C#4.0中有哪些功能不依赖于.Net 4.0的特性。 - Earlz
这真是太棒了。从Ed的帖子中,关于泛型方差的一个重要观点是,如果你的目标是3.5版本,IEnumerable<T> 将不会参与到方差特性中,因此你将不能摆脱所有烦人的 Cast<T> 调用,直到你能够以4.0运行时为目标。 - Daniel Earwicker
@Earlz - 难道这个回答中的项目符号列表不就是为此而设吗? - Daniel Earwicker
同时向 Ed Maurer 致敬,他等待了 18 个月才更新他(非常有趣的)博客! - Daniel Earwicker
+!@Daniel,是的,但那是被编辑过的...而且是一篇不错的博客文章。这是否基本涵盖了所有新功能? - Earlz

2

我知道在CLR 2.0中,通过类型参数中的IL注释+和-支持协变性和逆变性。不确定其他功能是否也有支持。


2

这不是一个列表,也不是最终版本,但作为一个例子,我刚刚建立了一个新的VS2010项目,目标是.NET 3.5,并成功创建了一个带有默认参数的方法,并使用命名参数调用它,这两个功能都是C# 4.0的特性。


0

我正在考虑对“旧”规范的更改……由于需要新的重载,lock更改将不可用,但“类似字段的事件”更改 应该可以工作。我必须检查编译器发出了什么;-p

果然如此:

using System;
class Program
{
    public event EventHandler SomeHandler;
    static void Main() { }
}

获取新式访问器 ;-p


@Marc:你所说的“锁定更改”是什么? - R. Martinho Fernandes
@Earlz - 请查看链接;类似于字段的事件实现已更改。 - Marc Gravell
@Martinho http://blogs.msdn.com/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix.aspx - Marc Gravell

0

考虑到默认参数已经是VB.NET的一个特性,因此C#可能只是在编译器级别实现了它。然而,CLR团队也可能完全采用了一种新的方式来实现它。

你应该修改你的问题,陈述“C# 4.0的哪些特性是编译器更改,适用于.NET 3.5框架”


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