c# - 使用外部库时 C# 8.0 可为空的引用类型的好处
问题描述
我目前正在将 ASP.NET Core 2.1 项目更新到 .NET 5,同时尝试利用一些较新的 C# 语言功能,例如:C# 8.0 的可为空引用类型
我尝试为我的一个项目启用它,并开始处理一些弹出的警告。在一个地方,我正在压缩一个文件夹,其中有一些调试日志记录:
var dirInfo = _fs.DirectoryInfo.FromDirectoryName(absPath);
var subEntries = dirInfo.GetFileSystemInfos();
foreach (var info in subEntries)
{
var isDirInfo = IsDirectory(info.Attributes);
_logger.Debug("Adding item to archive with parameters: type={type}, name={name}, bytes={size}",
isDirInfo ? "directory" : "file",
info.Name,
isDirInfo ? 0 : (info as FileInfoBase).Length);
// ~~~~~~~~~~~~~~~~~~~~
// CS8602: Dereference of a possibly null reference.
AddToZip(archive, info.FullName, Path.Join(entryPath, info.Name), isDirInfo);
}
上面的代码片段_fs
来自IFileSystem
System.IO.Abstractions库。上面的确切警告与此处的实际问题无关,但我对如何正确修复它的调查让我想知道为什么代码片段的第二行没有显示警告。签名中没有任何内容FromDirectoryName
表明它不能为空,因为该库尚未使用此功能。因此,我希望编译器假定dirInfo
它可能为 null 并在尝试在第二行取消引用它时显示警告。(让我们假设它会返回 null 而不是在不存在时FromDirectoryName
抛出异常- 这是我目前最好的现实世界示例)absPath
据我能够在互联网上找到,这是预期的。换句话说:因为FromDirectoryName
isIDirectoryInfo
和 not的返回类型,IDirectoryInfo?
编译器的行为就好像dirInfo
永远不会为空。我不知道这是设计选择还是技术限制,但这让我想知道这种新的可空引用类型有什么好处。对我来说,似乎无法依靠编译器来警告您使用从外部库返回的值,这破坏了这个“新”功能的很大一部分,因为它可能会导致您忽略潜在的空引用异常。
我是在上面的代码片段中错误地解释了编译器的行为,还是在依赖于多个外部库的项目中使用可空引用类型的方法有误?我希望您能帮助我了解如何在这种情况下使用此语言功能。
编辑(13-01-2021):
在Microsoft 的一篇博文中,他们甚至指出,您不能相信编译器能够解释尚未启用该功能的库中的方法签名。它强化了我的理论,除非你正在处理一个只有很少的 3rd 方库的项目,否则你很可能会浪费时间来实现这个功能,并且仍然无法获得 null 安全代码。
编辑(14-01-2021):
添加了一个可重现的示例:https ://github.com/Xerillio/csharp8-nrt-test
解决方案
推荐阅读
- amazon-mws - 亚马逊 MWS API 在不使用 Feed 的情况下更新库存
- c# - elasticsearch nest 的搜索问题 - 路由错误。您请求的路径无效
- python - 我们可以使用 Python 的 request.post 上传带有进度条回调的文件吗?
- reactjs - TypeError:无法读取空反应挂钩的属性“数据”
- python-3.x - python 正则表达式或其他
- mysql - 将 Substring_Index 与第二个表中的数据一起使用
- android - 未配置 NDK。使用 SDK 管理器下载它。首选 NDK 版本是“21.0.6113669”
- python - 使用数据框名称添加列
- aws-sdk - 如何从 C# / .net core 调用 AWS API Gateway
- python - 如何在python中更改日期时间格式?