gpt4 book ai didi

c# - MSBuild v14 在极少数情况下会编译语义不正确的程序集

转载 作者:可可西里 更新时间:2023-11-01 09:11:37 26 4
gpt4 key购买 nike

构建环境更新后,我们的一项冒烟测试在 TeamCity 中出现故障。调查结果表明,从相同的源代码,

  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe 生成正确的二进制文件
  • C:\Program Files (x86)\MSBuild\14.0\bin\MSBuild.exe 生成不正确的二进制文件

什么时候发生

  • 使用“params object[]”
  • 只传递一个值,没有显式包装在数组中
  • 使用命名参数
  • 与方法签名中的顺序不同

重现它的示例代码

static void Main(string[] args)
{
var customerId = Guid.NewGuid();

// Produces buggy code when compiled with MSBuild v14
TestMethodWithParams(args: customerId, whatever: "foo");

//All the calls below result correct behavior, regardless of the version of MSBuild, order and naming of parameters
TestMethodWithParams("foo", customerId);
TestMethodWithParams(whatever: "foo", args: customerId);

TestMethodWithParams(args: new object[] { customerId }, whatever: "foo");
TestMethodWithParams("foo", new object[] { customerId });
TestMethodWithParams(whatever: "foo", args: new object[] {customerId});
}

private static void TestMethodWithParams(string whatever, params object[] args)
{
Console.WriteLine("args: '{0}'", args);
}

到底发生了什么

不正确的版本只是吞掉了单个参数,null 被传递了。反编译代码显示差异:

在正确的二进制文件中:

Guid guid = Guid.NewGuid();
Program.TestMethodWithParams("foo", new object[]
{
guid
});

在不正确的二进制文件中:

Guid guid = Guid.NewGuid();
object obj;
Program.TestMethodWithParams("foo", new object[]
{
obj // <- this is and will always be null
});

如何修复

当我们将单个参数包装到一个对象数组中时,问题就消失了。另一种选择是不使用命名参数,和/或确保参数在调用和签名中出现的顺序相同。

但是:主要问题是我们无法恢复到旧的 MSBuild (...),并且检查整个代码库(并检查我们 NuGet 包中的每一个二进制文件)并不是一件容易的事和有效的解决方案。此外,这种错误可能会在以后的任何时候意外地重新引入代码库。因此,最好的解决方案可能是以某种方式修复 MSBuild。

有人遇到过这样的事情吗?可能是 MSBuild 中的错误?想法?

最佳答案

正如我在 GitHub 问题上提到的,我相信这是最初报告为 #4197 的错误。并在 Roslyn 1.1 中修复。

关于c# - MSBuild v14 在极少数情况下会编译语义不正确的程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37457082/

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