在 C# 中抑制警告 CS8670

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

通常,可以使用 null-forgiving 运算符 (!) 来抑制可空性警告。我刚刚遇到 CS8670对象或集合初始值设定项隐式取消引用可能为 null 的成员 并尝试使用 null-forgiving 运算符抑制它,但是那没有用,或者更准确地说我不知道将它放在哪里。这是一个例子:

class Program {
  public void M() {
    var x = new A
    {
      // Warning is here, when initializing "Items"
      Items = { "Hello", "World" }
    };
  }
}

class A {
  public List<string>? Items { get; init;} = new List<string>();
}

A
的代码在外部程序集中,所以我无法修改它。是否可以使用 null-forgiving 运算符抑制 CS8670?

c# roslyn roslyn-code-analysis nullable-reference-types
2个回答
0
投票

如果这是一次性的场景,那么

#nullable disable
/
#nullable restore
对,正如@Guru 提到的那样应该是好的。

另一种选择是放弃使用集合初始化器,而是使用

Items
访问
!
然后是
!

var x = new A();
x.Items!.Add("Hello");
x.Items!.Add("World");

// or
var items = x.Items!;
items.Add("Hello");
items.Add("World");

如果您发现这是代码中的常见模式并且发现这些解决方案不方便,您 可以 围绕此类引入一个包装器,但我认为这 太多了,无法解决可空性警告。因此,仅针对您的特定情况做出明智的判断:

using System;
using System.Collections.Generic;

// depending on how you are using "x", then var might work as well.
A x = new AWrapper
{
    Items = { "Hello", "World" }
};


class A
{
    public List<string>? Items { get; init; } = new List<string>();
}

public readonly struct AWrapper
{
    private readonly A _a = new();

    public AWrapper()
    {
    }

    public List<string> Items => _a.Items!;

    public static implicit operator A(AWrapper wrapper) => wrapper._a;
}

0
投票

!
是一元后缀运算符,似乎 ATM 它不能用于这种特殊情况,它基本上被翻译成一系列
Add
调用(@sharplab):

A a = new A();
a.Items.Add("Hello");
a.Items.Add("World");

您可以尝试使用

#nullable disable

var x = new A
{
#nullable disable
    Items = { "Hello", "World" }
#nullable restore
};

或者只是创建一个新的列表实例:

var x = new A
{
    Items = new(){ "Hello", "World" }
};

就个人而言,“一般情况下”我会选择第二个选项(除非是对性能非常敏感的代码),因为不能保证库作者在某个时候不会删除默认初始化。

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