我在一个面向 .NET Standard 2.0 的 C# (ClassLibrary) 项目中尝试了以下代码,它编译成功,同时它在另一个面向 .NET Core 3.1 的项目中给出了错误
private void SetOffset(out TimeSpan offset)
{
return;
}
.NET Core项目中的错误符合预期:
CS0177:在控制离开当前方法之前,必须分配输出参数“offset”
那是因为如果 struct 不包含任何字段,则认为它已赋值。例如:
private void SetOffset(out Test offset)
{
return;
}
struct Test {
void DoSomething() {
}
}
在 .NET Core 3.1(和其他 .NET 版本)中编译得很好。
现在,.NET 标准参考库中存在(是?)一个问题(这些库基本上只包含一个“存根”,并且在代码运行时实际使用“真实”库),即未包含私有字段,因此
.NET Standard 2.0 参考库中的 TimeSpan
不包含任何可访问字段,因此被视为由编译器分配,原因与上面的 Test
结构体相同。这个问题在这里有更详细的讨论。实际上,“不包含任何字段”可能更复杂,因为正如您在链接问题中所读到的那样 - 在此类参考程序集中,编译器可能会忽略某些字段。但最终结果是相同的 - 编译器将此结构视为不包含可访问字段并允许有问题的使用。
编辑删除了“可访问”:结构体字段的可访问性没有区别(请参阅 C# 8第 9.4.1 节,最新可用规范)。
private void SetOffset(out TimeSpan offset)
{
offset = new TimeSpan(); //reset all the timespan
}
你也可以这样做:
private void SetOffset(out TimeSpan offset)
{
DateTime date1 = new DateTime(2010, 1, 1, 8, 0, 15);
DateTime date2 = new DateTime(2010, 8, 18, 13, 30, 30);
offset = date1 - date2; //offset.Days will be -229 an will be passed a initialized timespan by minus
}