什么是针对框架的目标,如何最大化兼容性?

57

大家好,

自从我开始使用C#编码以来,这一直让我感到困惑。我的目标是创建一个程序集,可以在用户的最新.NET框架上运行,无论用户使用的是哪个版本。我不想要求安装.NET 4,但如果用户有它,我想使用它,更重要的是,如果用户只有.NET 4而没有其他版本,它仍然能够正常工作。我开始怀疑这甚至是不可能的。

我真的不理解当我在Visual Studio中更改“目标框架”时选择了什么。那是指“与此版本及以上版本兼容”还是“仅与此版本兼容”?到目前为止,它似乎是后者;我的虚拟机测试显示,针对.NET 4的程序集在没有.NET 4的情况下失败,而针对.NET 3.5的程序集在没有.NET 3.5的情况下失败。难道没有办法设置它以实现最大的兼容性吗?

更新:为了澄清,我有一个针对.NET 2的程序。这里的帖子似乎表明它应该在.NET 4上运行。但是,在只有.NET 4而没有它之前的环境中,它无法加载。

更新2:好吧,我弄清楚了,但比这里的帖子要复杂得多。我正在打开一个不同的问题来讨论细节,但简短版本是,如果你想在.NET 4上运行非.NET 4程序集,需要在其中添加一个<supportedRuntime version="v4.0" /> 的 app.config 文件。没有它,它们将无法加载。


1
请问您想写什么样的程序,需要使用最新的框架吗?在大多数情况下,使用最早期的框架编写应用程序是可以接受的,否则您将不得不针对特定的框架进行编译,并尝试根据安装版本进行混搭。 - Brad Christie
1
我并不是真的想使用最新的框架,而是希望只安装了.NET 4的用户不必下载和安装庞大的.NET 3.5框架。 - Paul Accisano
这里有一个SupportedRuntime逻辑的解释和示例:要将您的应用程序配置为在.NET Framework 4或更高版本上运行 - WileCau
4个回答

28

这些框架旨在向后兼容;如果你有一个使用 .NET 2.0 编写的程序,你可以在 4.0 运行时中运行它,因为框架从未删除先前版本存在的功能(这就是为什么我们仍然拥有非泛型集合,如 ArrayList,尽管它们已过时并被泛型集合取代)。但是反之不一定成立;4.0 应用程序不能保证在 2.0 中运行,因为它可能利用新的运行时特性,在之前的版本中不可用。无论如何,如果你希望你的应用程序尝试在其没有专门针对的运行时版本上运行,你必须在 app.config 中使用 SupportedRuntime 元素指定。

回答您的具体问题,您可以通过以下基本流程来实现:

  • 开发您的应用程序以针对您想要支持的最早的框架版本。这将禁用访问较新版本的较新运行时的新功能 (例如 3.5 中的 Linq 和 4.0 中的动态类型),确保您的应用程序不需要任何支持运行时无法提供的功能。

  • 通过在您的 app.config 文件中使用 SupportedRuntime 元素来指定适用于您的应用程序的框架。这将告诉初始化您的应用程序将运行的运行时的本机代码,如果无法找到目标版本,则任何其他版本都是可接受的。我相信行为是首先寻找目标框架,如果不可用,则使用最新支持的运行时。


2
如果新版本表现更好怎么办?我有一个可以在.NET Framework 2.0上工作的库,但我认为由于多年来进行的优化,它可能在更新的版本上表现更好。因此,我将目标设置为了4.6.1这个较新的版本。你对这种情况有什么看法? - yakya

2

.NET是向后兼容的,这意味着如果您选择.NET Framework 2.0作为目标框架,则它将在已安装的版本2.0、3.0、3.5和4.0上运行。但是,如果您选择了4.0版本作为目标框架,则只有在您安装了4.0版本时才能运行。


11
这是我原本的想法,但似乎并不是这样。我在一个只安装了.NET 4的虚拟机上测试了我的应用程序(它是一个扩展DLL),但它无法加载。如果我尝试使用ngen,会收到以下错误消息:Failed to load the runtime. (Exception from HRESULT: 0x80131700). Assembly {my assembly} requires version v2.0.50727 of the runtime to run. - Paul Accisano

1

0
我相信,这应该是选择的版本及以上。因此,如果你针对2.0框架进行开发,只要客户端安装了2.0、3.0、3.5或4.0框架,它就能正常工作。
当你选择这个时,你也在选择语言特性,所以我不知道有什么办法能够让你在一个针对2.0框架的应用程序中使用4.0框架的特性。即使动态加载程序集也不行,试着从一个2.0应用程序中加载一个编译到4.0的dll,它也不会让你这么做。

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