visual-studio - 调试针对 Framework 4.0 的项目时加载 Framework 4.5 程序集

标签 visual-studio visual-studio-2012 multitargeting

我需要能够使用 Visual Studio 2012 以 .NET Framework 4.0 为目标,并验证我的代码在我们的 4.0 环境 (Windows Server 2003) 上部署时是否能正常工作。

Visual Studio 2012 中的多目标似乎工作正常,但仅适用于 mscorlib.dll .当引用任何其他框架 DLL 时,编译时您会得到正确的错误,例如引用了4.0中不存在的类型,但在执行和调试时加载了4.5版本的DLL。

考虑到 4.5 版框架在就地升级中所做的重大更改,这使得无法验证我的代码是否能在生产环境中正常工作。

我进行了一些单元测试,通过使用 MSDN 上发现的 4.0 和 4.5 之间的一些差异来测试多目标功能。 .这些测试包含在他们自己的项目中,目标是他们正在测试的框架版本。所有测试都应该通过。

针对 MSCORLIB 的测试

这些测试成功通过 List<string>位于mscorlib.dll :

框架 4.0: - 通过 -

[TestMethod]
public void List_Foreach_should_not_throw_if_list_is_modified() {
    var list = new List<string> { "This", "here", "be", "a", "list", "of", "strings" };

    list.ForEach((s) => {
        if (s.Equals("be", StringComparison.OrdinalIgnoreCase)) {
            list.Add(".");
        }
    });
}

框架 4.5: - 通过 -

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void List_Foreach_should_throw_if_list_is_modified() {
    var list = new List<string> { "This", "here", "be", "a", "list", "of", "strings" };

    list.ForEach((s) => {
        if (s.Equals("be", StringComparison.OrdinalIgnoreCase)) {
            list.Add(".");
        }
    });
}

针对其他框架 DLL 的测试

但是这些测试不能正常工作(4.5 通过,4.0 不通过)因为这些类型在 System.ComponentModel.Composition.dll 中找到。并且始终加载 4.5 版本:

Framework 4.0 - 失败,抛出 4.5 预期的异常 -

[TestMethod]
public void Should_be_able_to_create_a_serializer_for_MEF_catalogs()
{
    var catalog = new AggregateCatalog();
    var serializer = new XmlSerializer(typeof(AggregateCatalog));
}

Framework 4.5 - 通过 -

[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Should_not_be_able_to_create_a_serializer_for_MEF_catalogs()
{
    var catalog = new AggregateCatalog();
    var serializer = new XmlSerializer(typeof(AggregateCatalog));
}

这是设计好的吗?考虑到加载了 4.0 版的 mscorlib 但加载了所有其他程序集的 4.5 版,这似乎是不相交的。

有没有办法获得我想要的功能?

更新

这是 solution/projects我正在使用的。

最佳答案

感谢伟大的重现!

在查看您的项目时,有两件事会影响您的结果,从而导致您所看到的行为:

1) 当我们检测到在 4.5 下运行的 4.0 应用程序时,我们“填充”更改的 API 以返回旧的 4.0 行为,当我们认为它可以从合理的(即非人为的)应用程序使用中观察到时。例如,依赖于修改 List.ForEach 中列表的能力的 4.0 应用程序将继续看到 4.0 行为,无论是在 4.0 还是 4.5 下运行。 4.5 应用程序将看到新的行为。

为了确定我们认为合理的用法并指导我们填充的 API,我们有一个兼容性团队负责检查整个框架中的每一个“破坏性”更改,并将其与一组规则和指南进行比较我们在过去 10 年中积累的经验。

在您附加的项目中,您正在测试 5 个项目:

  • List.ForEach 在 4.5 下修改列表时抛出 InvalidOperationException
  • 低于 4.5 的 Uri 现在在路径段中保留尾部点
  • 4.5 下的 Uri 不再转义?在基于 file://的 URI 中
  • 4.5 下的 Enumerable.Empty 现在保证它返回相同的实例(这个在文档中有点误导 [我已经提交了一个错误],我相信行为是在 4.0 上它可以返回两个不同的实例第一次被多进程机器上的两个不同线程访问,同时)
  • MEF 的目录不再是可序列化的 XML

在这些行为中,当 4.0 应用程序运行时,前三个被填充以返回 4.5 上的先前行为。然而,最后两个没有填充。这是因为最后两个更改会破坏非常人为的应用程序用法,在这种情况下,我们只是将它们记录在上面作为 FYI。例如,以 MEF 目录更改为例,虽然理论上您可以使用 XML 序列化程序序列化这些类型(这是无意的,恕我直言,这是 XML 序列化程序的可怕行为)但您无法对结果做任何事情,因为它没有反序列化为任何有用的东西。

如果我们可以修改该页面以包含为 4.0 应用程序填充的重大更改列表,我会继续努力。

2) 我遇到的第二个问题是 4.0 测试项目在与另一个基于 4.5 的测试项目运行时被错误地检测为 4.5。您可以通过自己运行 4.0 测试来观察这一点,三个 shimed 测试将​​通过。将它们与 4.5 测试一起运行,但它们失败了。我不确定这个问题是从哪里开始发挥作用的,但我已经在内部提交了一个错误,并与负责的团队启动了一个线程来深入了解它。如果您想从外部跟踪问题,请随时在 http://connect.microsoft.com/VisualStudio 上提交错误。我们会将它路由到正确的所有者。

大卫·基恩

CLR 团队

关于visual-studio - 调试针对 Framework 4.0 的项目时加载 Framework 4.5 程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12591336/

相关文章:

C++ do-While 循环不循环

c# - 警告 NETSDK1071 对 'Microsoft.AspNetCore.App' 的 PackageReference 指定了 `2.1.6` 的版本

c# - 在 Visual Studio 中通过 C# 类编译 C++ 代码

visual-studio-2012 - 为什么在项目文件中缺少 <SccProjectName> 导致 "The project file is not bound to source control"

.net - WPF 和 NET 3.5 到 4 多目标

c++ - CMake 在 Windows 10 下使用 GTest - fatal error LNK1104 : cannot open file 'gtest.lib' , 但存在调试 'gtestd.lib'

visual-studio-2012 - 通过 Visual Studio 发布时是否可以将单独的 Azure 角色部署到不同的服务?

javascript - VS2012 : Indentation of switch case in JavaScript when used with JSHint

cloud-foundry - 如何从带有目的地的 html5 应用程序轻松使用 nodejs-backend?

.net-3.5 - VS 2010 .NET Framework 问题(针对 3.5 的程序集)提示它需要更高版本的 .NET Framework