1

当使用索引初始化器填充字典而不在此之前重新创建它时,是否可以选择在某处指定容空运算符?

例子:

public class Program
{
    public IDictionary<string, string>? NullableDictionary { get; set; }
       = new Dictionary<string, string>();

    public static void Main(string[] args)
    {
        new Program
        {
            NullableDictionary =
            {
                ["key"] = "value"
            }
        };
    }
}

我知道这个用例(没有重新创建new Dictionary<string, string>索引初始化之前{ [...] = ... })可能不是很常见。但是我仍然想知道是否有解决方案可以防止上述情况出现此编译器警告:

[CS8602] 取消引用可能为空的引用。

我可以想象像这样使用 null-forgiving 运算符:

new Program
{
    NullableDictionary! =
    {
        ["key"] = "value"
    }
};
4

1 回答 1

1

我仍然想知道是否有防止此编译器警告的解决方案

我假设你的意思是,除了明显的#pragma方法:

#pragma warning disable 8602
    new Program
    {
        NullableDictionary = { ["key"] = "value" }
    };
#pragma warning restore

这显然有效。或者,当然,上面的“可空引用类型”特定版本:

#nullable disable
    new Program
    {
        NullableDictionary = { ["key"] = "value" }
    };
#nullable restore

这两个都暂时和明确地禁用有问题的警告。容错运算符本质上就是这样做的,当然除了它所应用的特定表达式。

无论好坏,我认为没有办法完全按照您的意愿行事。通常集合初始化器语法只允许在实际变量声明中使用。在对象初始化器语法上下文中使用它是语言允许的一种特殊情况,基于场景的相似性,即使生成的代码与实际的变量初始化有很大不同(尤其是你在实际上是在初始化集合的同时初始化变量的值)。

因此,当编译器处理您的集合初始化器语法时,编译器所要做的就是生成一堆对该Add()方法的调用,并且这些调用是针对可能为 null 的引用值进行的,根据您之前的声明。

综上所述,我发现您尝试在那里使用容错运算符是非常明智的。Add()如果编译器通过在它生成的每个调用中包含该运算符来解释该上下文中该运算符的使用,那就太好了。

您甚至可以针对该语言提出 Git 问题并要求将其添加为功能。我认为这不会是一个重大变化,因为该语法目前只是完全非法的,并且当您不使用该语法时,允许它不会改变编译器的行为。

于 2019-09-30T23:01:04.913 回答