为啥在面向 .NET Standard 的项目中可以不分配 Out 参数?
Posted
技术标签:
【中文标题】为啥在面向 .NET Standard 的项目中可以不分配 Out 参数?【英文标题】:Why an Out Parameter can be left unassigned in projects targeting .NET Standard?为什么在面向 .NET Standard 的项目中可以不分配 Out 参数? 【发布时间】:2021-02-06 16:27:46 【问题描述】:我在一个针对 .NET Standard 2.0 的 C# (ClassLibrary) 项目中尝试了以下代码,它编译成功,同时在另一个针对 .NET Core 3.1 的项目中出现错误
private void SetOffset(out TimeSpan offset)
return;
.NET Core 项目中的错误符合预期:
CS0177:必须在控制离开当前方法之前分配输出参数“offset”
【问题讨论】:
【参考方案1】:是这样的: 编译器不知道is是否会被初始化,那么你需要总是初始化
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
【讨论】:
问题是为什么代码在不应该编译的时候编译,而不是如何让代码编译。【参考方案2】:这是因为如果 struct 不包含可访问字段,则认为它已分配。例如:
private void SetOffset(out Test offset)
return;
struct Test
void DoSomething()
在 .NET Core 3.1(和其他 .NET 版本)中编译得很好。
现在,.NET Standard 参考库(这些库基本上只包含一个“存根”并且在运行代码时实际使用一个“真实”库)中存在(是?)一个问题,即不包含私有字段,所以 .NET Standard 2.0 参考库中的 TimeSpan
不包含任何可访问的字段,因此编译器认为是由编译器分配的,原因与上面的 Test
结构相同。这个问题在here 有更详细的讨论。实际上,“不包含任何字段”可能更复杂,因为您可以在链接的问题中阅读 - 在此类参考程序集中编译器可能会忽略某些字段。但最终结果是相同的 - 编译器将此结构视为不包含可访问字段并允许有问题的使用。
【讨论】:
以上是关于为啥在面向 .NET Standard 的项目中可以不分配 Out 参数?的主要内容,如果未能解决你的问题,请参考以下文章
无法在面向 .Net Standard 2.0 的项目中加载 Revit API
具有 .NET Standard 目标的 Azure 云服务经典
如何创建面向 .NET 2.0 和 .NET Standard 的库?
为啥 .NET Core 中 Enumerable.Zip() 的 2 参数重载但 .NET Standard 中没有? [关闭]
将 .NET Core 2.0 类库转换为 .NET Standard
为啥我们需要将 Swift 类标记为 `public` 或 `open` 以使其在 Objective-C 框架项目中可访问?