我的类库应该针对哪个.NET Framework和C#版本进行目标设置?

11

我正在构建一个DLL类库 - 我希望能够让尽可能多的人使用它。我应该使用哪个版本的.NET Framework和哪个C#版本?是否可以生成向后兼容的DLL或为不同版本生成不同的DLL?还是Windows会自动更新.NET Framework,所以我应该只使用最新版本?欢迎任何指导!

12个回答

11

个人建议,我会以.NET 2.0为目标。这意味着,除其他事项外:

  • 没有扩展方法(虽然有解决方法)
  • 没有Linq

  • 可以使用Lambda表达式

  • 可以使用“var”关键字

问题是,您可以使用C# 3.x语言特性(所谓的语法糖),但不能使用针对C# 3.x的库(例如System.Core,其中包括扩展方法和Linq)。

我不会尝试支持C# 1.x,因为它与C# 2.x及更高版本相差很大。此外,我预计大多数使用您的库的人是构建新项目的人,他们不会愚蠢到使用C# 1.x ;-)


10

我们针对某些产品同时针对多个运行时版本(.NET 1.1、.NET 2.0 和 .NET 3.5)。

我们有几种处理方式:

  • 为每个 .NET 1.1、2.0 和 3.5 SP1 分别创建解决方案和项目文件,但引用相同的源文件。

例如:

\ProductFoo_1_1.sln(.NET 1.1解决方案,VS 2003)
\ProductFoo_2_0.sln(.NET 2.0解决方案,VS 2008)
\ProductFoo_3_5.sln(.NET 3.5解决方案,VS 2008)
\FooLibrary\FooLibrary_1_1.csproj(.NET 1.1项目,VS 2003) \FooLibrary\FooLibrary_2_0.csproj(.NET 2.0项目,VS 2008) \FooLibrary\FooLibrary_3_5.csproj(.NET 3.5项目,VS 2008)
\FooLibrary\FooClass.cs(在所有项目中共享) \FooLibrary\FooHelpers_1_1.cs(仅由.NET 1.1项目引用)
\FooService\FooService_3.5.csproj(.NET 3.5项目,VS 2008) \FooService\FooService.cs
  • 在每个解决方案中定义NET_X_X符号

  • 对于特定于.NET Framework的代码,我们使用预处理器指令,例如:

public void SomeMethod(int param) { #ifdef NET_1_1 // 需要使用辅助方法在 .NET 1.1 下获取 Foo Foo foo = Helper.GetFooByParam(param); #elseif NET_2_0 || NET_3_5 // .NET 2.0 及以上版本可以使用首选方法 var foo = new Foo { Prop = param }; foo.LoadByParam(); #endif foo.Bar(); }
#ifdef NET_3_5 // 仅在 .NET 3.5 下可用的一个方法 public int[] GetWithFilter(Func Filter) { // 在此处添加一些代码 } #endif
为澄清起见,以 # 开头的行是预处理器命令。编译解决方案时,C# 编译器 (csc) 对源文件进行预处理。 如果您有一个 #ifdef 语句,那么 csc 将评估以确定该符号是否已定义 - 如果是,则在编译项目时包括该段内的行。
这是一种将代码标记为在特定条件下编译的方法 - 我们还可以使用它在特定详细的调试版本中包含更深入的调试信息,例如:
#if DEBUG_VERBOSE
  Logging.Log("使用参数调用 Web 服务:param = " + param);
  Logging.Log("Web 服务响应:" + response); 
  Logging.Log("当前缓存大小(字节):" + cache.TotalBytes); 
  // 等等。 
#endif
我们有一些NAnt脚本,可自动化为每个 .NET 版本制作发布版。 我们恰好通过TeamCity控制所有这些内容,但我们也可以手动触发NAnt脚本。
这确实使事情变得更加复杂,因此我们只倾向于在需要维护遗留的.NET 1.1或2.0实例时执行它(例如,客户无法/不会升级)。
我想当.NET 4.0推出时,我们会做同样的事情,并添加一个 NET_4_0 符号。

9

如果您没有使用3.0或3.5的功能,我建议您将其保留在2.0版本。


2
虽然我理解你的观点,但这种方法似乎会减缓/阻碍对较新版本的 .net 的采用。 - Tony
5
@Tony - 我不这么认为。人们应该因为新事物有用而采纳它们,而不是因为它们是新的。 - Otávio Décio

4
尝试这个:
将目标模式切换到框架2.0(删除System.Core引用)。
如果它不能编译,则尝试添加对linqbridge.dll的引用:
如果还是不行,则应该针对3.5。

但如果他添加了对第三方dll的引用,那么他也需要发布它。此时,他应该使用.NET 3.0或更高版本。 - Tony
linqbridge非常小,它足够使用。我从.NET 2.0开始,并继续在VS 2008上定位它,同时享受C# 3的功能。 - Michael Buen
@Tony: 我想这要看你需要什么;) - kentaromiura
+1 提到了 linqbridge.dll。当然知道这个概念,但还不知道这个特定的库。 - peSHIr

2
如果我要开始一个新项目,我会始终使用最新的运行时!如果有3.5版本可用,为什么我需要在2.0或1.0中开始一个项目,除非我知道新版本有严重问题?新版本意味着修复旧漏洞并添加新功能,所以这是好的。
当涉及到将旧项目升级到新版本时,您需要考虑您的收益和损失。如果值得,就升级它,如果不是,请坚持使用旧版本。
但是要小心,因为新工具可能不支持旧版本。虽然这在2010年不是问题,因为它将支持所有版本直至2.0。

0

这个解决方案非常有效。我只需设置两个不同的项目,每个项目都有独特的“项目属性->构建->条件编译符号”,并在代码中像这样使用:

#if NET_4
            xmlReaderSettings.DtdProcessing = DtdProcessing.Ignore; 
#endif
#if NET_3_5
            xmlReaderSettings.ProhibitDtd = false;                
#endif

0

结合使用类似Will Hughes提到的方法,如果想在开发过程中获得访问/使用新功能的选项,请使用最新的框架。当准备开始制作发布候选版本时,将其设置为最低的框架,然后在出现问题时逐步提高框架版本和/或使用#ifdef方法解决。


0
我投票支持Erik van Brakel的答案。 此外,我想建议如果您想支持3.5功能,如LINQ和扩展方法,可以创建一个额外的库,比如说。

MyLibrary.DLL

MyLibrary.LINQ.dll

因此采用与微软相同的方法(他们在保留System.dll 2.0版本的同时,将所有新功能添加到System.Core.dll中)


0
我会针对版本2.0使用包含核心功能的库,并添加一个额外的库,针对3.5版本添加一些基于核心库的扩展方法。

总有可能两个人会写出相同的答案 :) - Bogdan_Ch

0
从我个人的角度来看,如果你想要获得更广泛的用户群,建议你使用早期版本,比如1.1会比较合适,因为它可以在任何装有.Net的机器上运行,不论其版本如何。

个人认为这不是一个好主意。主要是因为.NET 1.X和.NET2.0之间有许多重大变化。 - Tony

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