为啥 C# 6.0 在使用 Null 传播运算符时不允许设置非 null 可空结构的属性?

Posted

技术标签:

【中文标题】为啥 C# 6.0 在使用 Null 传播运算符时不允许设置非 null 可空结构的属性?【英文标题】:Why C# 6.0 doesn't let to set properties of a non-null nullable struct when using Null propagation operator?为什么 C# 6.0 在使用 Null 传播运算符时不允许设置非 null 可空结构的属性? 【发布时间】:2015-09-11 03:43:40 【问题描述】:

假设我们有以下代码:

struct Article

    public string Prop1  get; set; 


Article? art = new Article();
art?.Prop1 = "Hi"; // compile-error

编译错误是

CS0131 赋值的左侧必须是变量、属性或索引器。

其实art?.Prop1是一个属性,应该被认为是一个有效的赋值! 我没有看到任何使此代码无效的分配问题。

为什么 C# 6.0 不允许设置非 null 可空结构的属性? 或者,任何关于使分配有效的行代码的建议都将不胜感激。

【问题讨论】:

删除art?.Prop1 = "Hi"; 行中的问号,您的分配不应引发错误。让它art.Prop1 = "Hi"; @K.AlanBates 他特别想使用空传播运算符。 C# 中的结构只是为了让你的生活变得有趣。试试List<Article> articles = new List<Article> new Article() ; article[0].Prop1 = "test"; - 也许你会在那时重新考虑使用结构:)。 Mahdi,我已更改标题以匹配答案 - 如果它不符合您的意图,请随时恢复/改进。 @Servy 你说他专门使用它。我说他不小心使用了它,他的问题是如何将他的“Hi”分配给 Prop1 传递编译。使其通过编译的最简单方法是删除可能。 【参考方案1】:

这段代码:

Article? art

将定义一个Nullable<Article>,但稍后再定义:

art?.Prop1 = "Hi";

这意味着使用 Null 传播/条件运算符。

Null 传播/条件运算符用于访问属性,而不是设置它们。因此你不能使用它。

正如@Servy 在 cmets 中所说,Null 条件运算符的结果始终是一个值,您不能将值分配给一个值,因此会出现错误。

如果您只是尝试设置属性,那么您不需要 ? 和对象名称,?Nullable<T> 类型在声明时使用,这是语法糖:

Nullable<Article> art; //same as Article? art

【讨论】:

或者从技术上说同样的事情,空传播运算符的结果始终是一个值,而不是一个变量,这就是为什么他得到错误说他不能为一个值,因为它不是一个变量。 问题仍然是为什么不允许这样做。编译器可能会注意到它是一个赋值,然后使用空传播运算符返回变量/属性而不是值,还是我忽略了什么?可用于通过在执行分配之前省略空检查来简化代码。 既然您已经可以调用像 x?.SetValue(...) 这样的方法,那么属性分配(同样的事情)应该是一个有效的选项。为什么不呢?【参考方案2】:

Article? artNullable&lt;Article&gt; art 的快捷方式 要分配属性,您需要访问Nullable&lt;T&gt;.Value 字段。在一般情况下,您需要确保 art 不为空:

if (art.HasValue)

    art.Value.Prop1 = "Hi"; 

【讨论】:

以上是关于为啥 C# 6.0 在使用 Null 传播运算符时不允许设置非 null 可空结构的属性?的主要内容,如果未能解决你的问题,请参考以下文章

c#:为啥当我尝试在模拟中使用合并运算符时它不起作用

为啥 is 运算符在给定 null 时返回 false?

Python链式属性访问中的无传播[重复]

问号和点运算符是啥意思?在 C# 6.0 中是啥意思?

使用 C# 6.0 功能运行 TFS 构建

C# 6.0 是不是适用于 .NET 4.0?