gpt4 book ai didi

c# - 存在但未调用扩展方法时代码执行的差异

转载 作者:可可西里 更新时间:2023-11-01 08:29:33 25 4
gpt4 key购买 nike

TL;DR,问题:

.NET 中扩展方法的存在对代码的执行有什么影响(例如 JIT/优化)?

背景

我在 MSTest 中遇到测试失败,这取决于是否也测试了看似无关的程序集。

我注意到测试失败,并且偶然注意到只有在加载另一个测试程序集时才会发生失败。在单元测试和集成测试程序集上运行 mstest 将开始执行集成测试,并在 4.5 CLR 下的第 21 次集成测试中失败,而在 4.0 CLR 下不会发生这种情况(否则配置相同)。我从集成测试程序集中删除了所有测试,但失败的测试除外。执行现在看起来像这样,加载了两个测试程序集,mstest 加载了两个程序集,然后在集成测试程序集中执行单个测试,但失败了。

> mstest.exe /testcontainer:Unittests.dll /testcontainer:IntegrationTests.dll

Loading C:\Proj\Tests\bin\x86\Release\Unittests.dll...
Loading C:\Proj\Tests\bin\x86\Release\Integrationtests.dll...
Starting execution...

Results Top Level Tests
------- ---------------
Failed Proj.IntegrationTest.IntegrationTest21

在执行中没有 Unittests 程序集的情况下,测试通过。

> mstest.exe /testcontainer:IntegrationTests.dll

Loading C:\Proj\Tests\bin\x86\Release\Integrationtests.dll...
Starting execution...

Results Top Level Tests
------- ---------------
Passed Proj.IntegrationTest.IntegrationTest21

我认为它一定是在 UnitTests dll 上执行的 [AssemblyInitialize] 东西,或者可能是 Unittest.dll 中的某种静态状态或测试程序集时修改的公共(public)依赖项被加载。我在 Unittests.dll 中找不到任何静态构造函数和程序集初始化。我怀疑包含 Unittests 程序集时存在部署差异(依赖程序集部署在不同版本等),但我比较了通过/失败的部署目录,它们是二进制等效的。

那么 Unittests 程序集的哪一部分导致了测试差异?从单元测试中,我一次删除了一半的测试,直到我将其深入到单元测试程序集中的源文件。与测试类一起,声明了一个扩展方法:

除了这个扩展类之外,Unittest 程序集现在包含一个虚拟测试类中的单个测试用例。仅当我有一个虚拟测试方法 声明的扩展方法时,才会发生测试失败。我可以删除所有剩余的测试逻辑,直到 Unittest dll 成为一个包含以下内容的文件:

// DummyTest.cs in Unittests.dll
[TestClass]
public class DummyTest
{
[TestMethod]
public void TestNothing()
{
}
}

public static class IEnumerableExtension
{
public static IEnumerable<T> SymmetricDifference<T>(
this IEnumerable<T> @this,
IEnumerable<T> that)
{
return @this.Except(that).Concat(that.Except(@this));
}
}

如果删除了测试方法扩展类,则测试通过。两者都存在,但测试失败。

这两个程序集都没有调用扩展方法,并且在执行集成测试之前没有在 Unittests 程序集中执行任何代码(据我所知)。

我确信集成测试足够复杂,优化中的 JIT 差异可能会导致差异,例如在浮点。这就是我所看到的吗?

最佳答案

可能是由于类型加载错误导致的。

当 CLR 运行时加载类或方法时,它始终会检查这些项目中使用的所有类型。类型/方法是否实际被调用并不重要。重要的是声明的事实。返回到您的示例,扩展方法 SymmetricDifference 声明它使用 System.Core 程序集中的 ExceptConcat 方法。

从 System.Core 程序集加载 System.Linq.Enumerable 类型时发生错误。

该行为的原因可能各不相同。要采取的第一步是记录您在测试失败时遇到的确切异常。

关于c# - 存在但未调用扩展方法时代码执行的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21825738/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com