在构建环境更新后,我们的一项Smoke Tests在TeamCity中爆发。调查结果显示,来自相同的源代码,
何时发生
重现的示例代码
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);
}
究竟发生了什么
错误的版本吞下单个参数,传递。反编译代码显示了差异:
正确的二进制文件:
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中的一个错误?想法?
答案 0 :(得分:4)
正如我在GitHub问题上已经提到的那样,我认为这是最初报告为#4197并在Roslyn 1.1中修复的错误。
答案 1 :(得分:2)
感谢您提供所有信息和建议。您分享了有助于我们追踪此问题的详细信息。原来,安装“Microsoft Build Tools 2015 with Update 2”解决了我们的问题。
再次感谢大家。 /大卫