c# - 可空接口不触发 CS8602
问题描述
我现在遇到过几次启用可空且标记为可空接口类型的属性或字段(带有附加的?
),然后如果我在没有空检查的情况下使用该属性或字段,我不会收到任何错误。(我希望CS8602 - Dereference of a possibly null reference.
,并且在具体类型属性和字段中我确实收到此错误)。
我不确定这是 Roslyn 错误还是我没有充分理解的东西。
附加信息:
- .NET 5
- C# 9
namespace dotnet_scratch {
interface IFoo {
string? name { get; set; }
void fooAction ();
}
interface IFooGeneric<T> {
string? name { get; set; }
void fooAction( );
}
public class FooClass {
IFoo? fooInterface;
IFooGeneric<string>? fooInterfaceString;
FooClass? fooClass;
void doStuff( ) {
System.Console.WriteLine( fooInterface.name );
System.Console.WriteLine( fooInterfaceString.name );
fooInterface.fooAction();
fooInterfaceString.fooAction();
fooClass.fooAction();
}
void fooAction () {}
}
}
在捕获中,标记了三个突出显示的错误:
(field) IFooGeneric<string>? FooClass.fooInterfaceString
'fooInterfaceString' may be null here.
Dereference of a possibly null reference. [dotnet_scratch]csharp(CS8602)
另外将鼠标悬停fooInterface.fooAction()
并fooInterfaceString.fooAction()
说:
'fooInterfaceString' 在这里不是空的。
我的问题是为什么一个属性或字段被标记为IInterfaceType?
未标记为可能为 Nullable,就像具体类型的属性和字段一样?
解决方案
编译器对变量是否可以具有空值的看法与变量的类型是类还是接口无关 - 它是否先前被取消引用。
您收到以下两行的警告:
System.Console.WriteLine( fooInterface.name );
System.Console.WriteLine( fooInterfaceString.name );
...因为这是第一次取消引用这些变量中的每一个。但是编译器假设如果这两行都执行了而没有抛出异常,那么以后使用相同的变量:
fooInterface.fooAction();
fooInterfaceString.fooAction();
... 会没事的。在执行流程的这一点上,这两个变量都不能为空,因为否则前面的行之一会引发异常。(“可空性流程”没有考虑到另一个线程可能会改变中间变量的值。)
推荐阅读
- r - geom_errorbar 出现很多错误栏
- mysql - 如何创建包含“。”的表 特点?
- regex - 具有特定要求的正则表达式网址?
- c++ - C++ - 读取 .gz 文件,解压缩并写入另一个文件
- amazon-web-services - EC2 ecs 集群、ALB 和服务发现(在任务定义中使用 awsvpc 模式和桥接模式)
- javascript - 如何在新的 BrowserWindow(模态或 2e 窗口)电子应用程序中发送数据
- algorithm - 谁创造了递归除法迷宫算法?
- odata - SAP Fiori 应用程序 OData V2:sap-client 未在 onExit 事件函数导入调用中传输
- python - Dockerfile:OSError:没有可用的默认输入设备 Python
- r - 将 for 循环嵌套到矢量化函数并在数据框中保存值