可空接口不触发 CS8602
Nullable Interface does not trigger CS8602
我现在遇到过几次启用 nullable 并且 属性 或字段标记为可空接口类型(附加 ?
),那么如果我在没有空检查的情况下使用 属性 或字段,我不会收到任何错误。 (我希望 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?
的字段不像具体类型的属性和字段那样被标记为潜在可空?
编译器对变量是否可以有 null 值的看法与变量的类型无关 class 或者它是否是一个接口 - 它是否以前被取消引用。
您收到了这两行的警告:
System.Console.WriteLine( fooInterface.name );
System.Console.WriteLine( fooInterfaceString.name );
... 因为这是第一次取消对每个变量的引用。但是编译器假定如果 那些 行都已执行而没有抛出异常,那么以后使用相同的变量:
fooInterface.fooAction();
fooInterfaceString.fooAction();
...会没事的。到执行流程中的这一点,两个变量都不能为空,否则前面的行之一会抛出异常。 (“可空性流程”没有考虑到另一个线程可能会在中间更改变量值的可能性。)
我现在遇到过几次启用 nullable 并且 属性 或字段标记为可空接口类型(附加 ?
),那么如果我在没有空检查的情况下使用 属性 或字段,我不会收到任何错误。 (我希望 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?
的字段不像具体类型的属性和字段那样被标记为潜在可空?
编译器对变量是否可以有 null 值的看法与变量的类型无关 class 或者它是否是一个接口 - 它是否以前被取消引用。
您收到了这两行的警告:
System.Console.WriteLine( fooInterface.name );
System.Console.WriteLine( fooInterfaceString.name );
... 因为这是第一次取消对每个变量的引用。但是编译器假定如果 那些 行都已执行而没有抛出异常,那么以后使用相同的变量:
fooInterface.fooAction();
fooInterfaceString.fooAction();
...会没事的。到执行流程中的这一点,两个变量都不能为空,否则前面的行之一会抛出异常。 (“可空性流程”没有考虑到另一个线程可能会在中间更改变量值的可能性。)