为什么我没有收到有关在C#8中使用结构的类成员可能会取消引用null的警告?

问题描述 投票:1回答:2

在启用了可为空的引用类型的C#8项目中,我有以下代码,我认为应该向我发出有关可能的null取消引用的警告,但不会:

public class ExampleClassMember
{
    public int Value { get; }
}

public struct ExampleStruct
{
    public ExampleClassMember Member { get; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var instance = new ExampleStruct();
        Console.WriteLine(instance.Member.Value);  // expected warning here about possible null dereference
    }
}

[使用默认构造函数初始化instance时,instance.Member设置为ExampleClassMember的默认值,即null。因此,instance.Member.Value将在运行时抛出NullReferenceException。据我了解C#8的可空性检测,我应该收到关于这种可能性的编译器警告,但我没有。为什么呢?

c# nullable c#-8.0
2个回答
0
投票

请注意,对Console.WriteLine()的呼叫没有理由发出警告。引用类型属性不是可为null的类型,因此编译器无需警告它可能为null。

[您可能会争辩说,编译器应警告struct本身中的引用。在我看来,这是合理的。但是,事实并非如此。这似乎是一个漏洞,是由值类型的默认初始化引起的,即,必须始终有一个默认(无参数)构造函数,该构造函数总是始终将所有字段清零(对于引用类型字段为空,对于数字类型为零,等等)。 )。

我称它为漏洞,因为从理论上讲,不可为空的参考值实际上应该始终为非!咄。 :)

此博客文章中似乎解决了此漏洞:Introducing Nullable Reference Types in C#

避免为空到目前为止,警告是关于防止可空引用中的空值被取消引用。硬币的另一面是要避免在不可为空的引用中完全没有为空。

有多种方法可以产生空值,并且其中大多数值得警告,而其中一些将引起另一“警告之海”,最好避免:…

  • 使用具有非空引用类型字段的结构的默认构造函数。这是一个偷偷摸摸的工作,因为默认构造函数(将结构归零)甚至可以在很多地方隐式使用。 可能最好不要发出警告 [强调我的],否则许多现有的结构类型将变得无用。

换句话说,这是一个漏洞,但不是漏洞。语言设计者已经意识到了这一点,但是选择将这种情况保留在警告范围之外,因为鉴于struct初始化的工作方式,否则这样做是不切实际的。

© www.soinside.com 2019 - 2024. All rights reserved.