本文描述了可能会影响到应用程序向后兼容和向前兼容的.net版本变化。包含如下内容:导致不兼容的类型,修改应用程序以解决非兼容性,以及如何在不同版本.net框架中测试和运行你的应用程序。这些信息虽涉及范围广泛但并不是一份完全清单,因此如果你需要更进一步的帮助,请联系产品支持服务(PSS)(http://go.microsoft.com/fwlink/?linkid=3551)。
* 对在1.0版.NET框架下开发,而在1.1版.NET框架上发布的应用程序会产生影响的变化清单,参见《从版本1.0到版本1.1的影响向后兼容的变化清单》(http://www.gotdotnet.com/team/changeinfo/Backwards1.0to1.1/default.aspx)。
* 对在1.1版.NET框架下开发,而在1.0版.NET框架上发布的应用程序会产生影响的变化清单,参见《从版本1.0到版本1.1的影响向前兼容的变化清单》(http://www.gotdotnet.com/team/changeinfo/Forwards1.0to1.1/default.aspx)。
* 关于1.0版和1.1版中公共API的变化的清单(既包括可能影响兼容性的,也包括可能不会影响兼容性的),参见《API的变动》(http://www.gotdotnet.com/team/upgrade/apiChanges.aspx)。
兼容性和中断性变化
.NET框架试图在不同版本间保持向后和向前兼容性。但是,针对.NET框架提高安全性、正确性和功能的改变,也会导致兼容性问题出现。
向后兼容性指在1.0版.NET框架下开发的应用能够在1.1版下执行。.NET框架最高程度的支持向后兼容性。几乎所有在当前.NET框架版本下工作的的应用程序都可以在下一版本.NET框架中工作。
向前兼容性指在1.1版.NET框架下开发的应用能够在1.0版下执行。虽然.NET框架支持向前兼容性,但是如果应用程序使用了1.1版专用的类型或者成员,在1.0版本下将永远不能合适运行。永远无法指望这样的应用能够工作,这并不是向前不兼容的问题。如果你希望你的应用能同时在.NET框架的两个版本下合理运行,你应该在程序中只使用1.0版所拥有的类型和成员。
中断性变化
一个中断性变化是指二进制或者行为变化,改变了.net框架的类型或成员,导致应用程序不能向前或向后兼容。一个向后的中断性变化导致在1.0版.net框架下编写的程序无法在1.1版下合理执行,而一个向前的中断性变化导致在.net1.1下编写的程序无法在1.0版下正确执行。
向后中断性变化主要是为了实现加强的安全性机制,而向前中断性变化通常是为了修改1.0版中的错误。
二进制中断性变化
二进制中断性变化意味着类型或者成员的名称改变了。这种变化包括从改变方法参数名到改变方法本身的名字,改变返回值的类型。二进制变化通常是向前向后不兼容的。
虽然在1.1版.net框架中存在二进制变化,但是这些变化的影响很小。因为这些修改仅仅应用于那些在1.0版本中保留的或者技术上不可用的那些类型或成员。
行为中断性变化
行为中断性变化指操作类性或成员的方式改变了。行为中断性变化通常是微妙的、难于与二进制中断性变化区分开。行为中断性变化可能是向后不兼容,向前不兼容,或者同时向后向前不兼容。
除了为修正代码错误或扩展可靠性和安全性以外,.Net框架很少产生行为中断性变化。
"重导"应用程序
通常,应用只工作在编译它的.NET框架版本环境下。此时,执行时不需要配置文件。但是,如果你希望在一种版本.NET框架下编译构造,在另外一种或者多种不同版本.NET框架下运行,那么你必须使用合适的配置文件。
指定应用程序要在其中运行的.NET框架版本,称作"重导"(redirecting)应用程序。一个应用程序能被"重导"于只在一特定版本的.net框架下使用。你可以使用VS.net自动生成配置文件,也可以按照下面提供的信息手工建立该文件。
如果程序没有配置文件,则在同一目录下建立一个。配置文件的名字是在你的应用程序名字后面加上".config".例如,如果应用程序的名字是MyApp.exe,那么相应的配置文件名称是MyApp.exe.config。
配置文件的标签
通过指定合适的配置文件标签来重导应用程序。在本例中,<requiredRuntime>标签用于"重导"程序使之适用于只安装了.net框架1.0版的机器。
<startup>
<requiredRuntime imageVersion="v1.0.3705" version="v1.0.3705" />
</startup>
对于1.0版.net框架,由于1.0版不能自动引用依赖的程序集,配置文件需要“重导”任何你的应用所依赖的程序集。也因此,配置文件可能变得相当庞大。本例中,"重导"了一个程序集到.net框架1.0版。
<dependentAssembly>
<assemblyIdentity name="Accessibility" publicKeyToken="b03f5f7f11d50a3a" culture=""/>
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="1.0.3300.0"/>
</dependentAssembly>
而在1.1版.net框架中,配置文件相对小得多,因为运行时会为你自动引用依赖的程序集。.net框架自动引用依赖的程序集的能力被称作"同一"(unification)。这意味着你只需要一个简单的配置文件统一你的程序和它引用的程序集,来适应特定的.net框架版本。
通过在配置文件中使用一个或多个<supportedRuntime>标签可以指出哪些.net框架版本可以让你的程序执行。标签的顺序决定了哪个版本的.net框架是首选。第一个标签指向的是你最想用的版本;如果那个版本没有安装,将使用第二个标签指向的版本,如此类推。
下面例子"重导"一个在1.0版.net框架下建立的程序到1.1版环境下执行。
<startup>
<supportedRuntime version="v.1.1.4322" />
</startup>
如果你的计算机中安装了1.1版.net框架,可以使用多个<supportedRuntime>标签入口指定多个.net框架版本。如果希望应用能在1.0版.net框架里运行,则还需要一个<requiredRuntime>标签,以及该应用使用的所有程序集的重导标签。
下面的例子中,首选使用.net框架的1.1版,但是如果没有该版本,则使用1.0版本。
<startup>
<requiredRuntime imageVersion="v1.0.3705" version="v1.0.3705" />
<supportedRuntime version="v.1.1.4322" />
<supportedRuntime version="v1.0.3705" />
</startup>
为应用程序和框架配置混合版本的文件
下面描述了在不同版本.net框架上运行不同版本的应用程序所需要的配置文件的一部分。
在.net框架1.0版上运行使用.net框架1.0建立的应用,不需要”重导”.这是.net框架1.0版应用的缺省行为。
但是如果在1.1版下运行使用1.0版建立的应用,则应用中应该包含像下面这样的配置文件:
<?xml version ="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v.1.1.4322" />
</startup>
</configuration>
为了能在1.0和1.1版下都能运行在1.0环境下建立的应用,配置文件中应该包含2个<supportedRuntime>标签和一个<requiredRuntime>标签。第一个<supportedRuntime>标签”重导”到.net框架1.0版。而<requiredRuntime>标签也”重导”到1.0版。
应该包含你的应用程序引用的所有程序集的”重导”节。重导这些程序集到1.0版,而1.1版不会使用这些配置节。
例如:
<startup>
<requiredRuntime imageVersion="v1.0.3705" version="v1.0.3705" />
<supportedRuntime version="v1.0.3705" />
<supportedRuntime version="v.1.1.4322" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Regcode" ublicKeyToken="b03f5f7f11d50a3a" culture=""/>
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535"
newVersion="1.0.3300.0"/>
</dependentAssembly>
<!-- Include a section for each assembly to be redirected. -->
</assemblyBinding>
</runtime>
在1.1版上运行使用1.1版建立的应用,不需要”重导”,这是1.1版.net框架的默认行为。
但是在1.0版上运行使用1.1版.net框架建立的应用,需要在指向.net1.0的配置文件中包含<requiredRuntime>标签,还要包含你的应用中引用的所有程序集的”重导”。
在1.1版或1.0版下运行在1.1版中建立的应用,应用程序的配置文件需要包括2个<supportedRuntime>标签和一个<requiredRuntime>标签。第一个<supportedRuntime>标签重导到.net框架1.1版。<requiredRuntime>标签重导到.net框架1.0版。
配置文件包含你的应用中引用的所有程序集的”重导”节。重导这些程序集到.net框架1.0版,1.1版不会使用这些配置节。
测试应用
在所有你想支持的.net框架版本中测试应用程序。特别的,在所有要运行你的应用程序的.net框架版本上测试应用程序。这意味着你应该在不同版本.net框架中重编译或者更改配置文件的设置来测试应用程序。
警告:修改一个Visual Studio .EET 1.0版工程
如果在1.1版visual studio.net 中打开1.0版visual studio.net建立的工程,会出现警告,提示会自动将该工程升级到1.1版,将应用程序升级到在1.1版.net框架下运行。当使用vs.net1.1版打开工程后,无法再使用1.0版vs.net打开该工程。即使你没有重新编译也是如此。而且,用后续版本的vs.net打开的工程,并不能自动保证仍然能够编译和运行。
为了在1.1版下运行1.0版.net框架建立的应用,可以在只安装了1.1版.net框架的独立计算机上执行测试。
1. 在1.0版下编译你的原始应用程序。
2. 生成必需的配置文件,指定在1.1版.net框架下运行。
3. 拷贝编译后的程序到只安装了1.1版.net框架的计算机上。
4. 运行程序。
为了在1.0版上运行1.1版的应用程序,应该在只安装了1.0版.net框架的计算机上进行测试。
1. 在1.1版.net框架中编译你的原始应用。
2.为1.0版运行环境生成必需的配置文件。
3. 拷贝编译后的程序到只安装了1.0版.net框架的计算机上。
4. 运行程序。如果运行失败,可能是你使用了某些1.1版.net框架的特定功能。如果是这样,你必须修改应用程序使之只使用1.0版.net框架的功能。
[译者:hahahawk]
[主页: http://CSharpOk.Net ]
[Email: CangQiong@Sina.Com ]
[译者附录]:
一、几个词语的翻译:
Breaking Changes:原文用来与那些兼容性问题相区别的版本变化。我把它翻译成破坏性变化或中断性变化,似乎都不贴切。
Redirecting:我没有把它翻译成"重定向",而是使用了"重导"。
二、关于asp.net中的版本问题:
此文对于那些深受版本问题困扰的人也许有所帮助。本人在vs.net2003下开发的aspx文件在1.0版框架下运行出错,直到看到这篇文章之后才解决。受本文启发,我根据出错信息里面提示的无法找到合适版本的程序集,在asp.net的配置文件web.config的<configuration></configuration>里"重导"了这些程序集。附录如下:
<configuration>
<system.web>
.......
</system.web>
<startup>
<requiredRuntime imageVersion="v1.0.3705" version="v1.0.3705" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System" publicKeyToken="b77a5c561934e089" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="1.0.3300.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml" publicKeyToken="b77a5c561934e089" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="1.0.3300.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Data" publicKeyToken="b77a5c561934e089" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="1.0.3300.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>