【问题标题】:Null Conditioning operator can't be used for assignments? [duplicate]Null Conditioning 运算符不能用于赋值? [复制]
【发布时间】:2016-09-02 16:53:38
【问题描述】:

请查看以下代码并帮助我了解我收到编译器错误的原因。

class Program
{
    static void Main(string[] args)
    {
        Sample smpl = GetSampleObjectFromSomeClass();

        //Compiler Error -- the left-hand side of an assignment must be a variable property or indexer
        smpl?.isExtended = true; 
    }
}

public class Sample
{
    public bool isExtended { get; set; }
}

我是否应该推断空条件仅用于访问属性、变量等而不用于赋值?

注意:我提到了一个类似的帖子(下面的链接),但在我看来,没有进行足够的讨论。Why C# 6.0 doesn't let to set properties of a non-null nullable struct when using Null propagation operator?

编辑: 我期待像

这样的东西
If(null!= smpl) 
{ 
smpl.isExtended = true; 
}

看来我的预期不对!

【问题讨论】:

  • 你的推论是正确的。空条件运算符仅适用于成员访问,不适用于赋值。我倾向于同意编译器应该允许它用于属性分配(但不是字段),因为属性分配实际上被编译为方法调用。编译后的属性分配看起来像:smpl?.set_isExtended(true); 这将是完全有效的代码。
  • @AndrewHanlon:有趣的观察 (+1),但语义和句法很难一起发挥作用。
  • 好的,鉴于 cmets,我已经重新打开了。
  • 不知道为什么人们会问“你希望它做什么” - 很明显你希望它做什么(从程序员的角度来看):如果它不为空,则进行分配。
  • 我的猜测是空条件运算符在 C# 语言中不是有效的左值。投票@jonskeet

标签: c# c#-6.0


【解决方案1】:

你的推论是正确的。空条件运算符仅适用于成员访问,不适用于赋值。

也就是说,我倾向于同意语言/编译器应该允许运算符用于属性分配(但不是字段),因为属性分配实际上被编译为方法调用。

编译后的属性赋值如下:

smpl?.set_isExtended(true); 

这将是完全有效的代码。

另一方面,很容易提出这样的论点,即它会在属性和字段使用之间引入当前不存在的语法差异,并使代码更难推理。

您还可以访问 codeplex 上的大部分 C# 6.0 design notes。我粗略地浏览了一下,空条件讨论跨越了很多部分。

【讨论】:

    【解决方案2】:

    考虑这行代码的含义:

    smpl?.isExtended = true;
    

    如果smpl null,您将尝试为null 分配一个值。这没有意义。

    只需赋值即可,无需进行空值检查:

    smpl.isExtended = true;
    

    基本上,空传播运算符用于读取值,而不是设置它们。考虑这行代码:

    var x = someObject?.someProperty;
    

    从概念上讲,这意味着如果someObject 存在,则x 将被分配someProperty 的值。如果它不存在(是null),那么x 将是null

    反过来说,这意味着什么?:

    someObject?.someProperty = x;
    

    从概念上讲,这意味着如果someObject 存在,则将someProperty 设置为x。但如果它不存在(是null)那么... 将null 设置为x?这没有意义:

    null = x;
    

    【讨论】:

    • 进行编辑只是为了说明我的情况,@David
    • @Vivek_Shukla:我也更新了答案。基本上,考虑两种情况下代码中会发生什么(是null 与不是null)。这两种情况之一是没有意义的。所以编译器拒绝了。
    • 难道不是说:如果someObject 存在,则调用someObject.set_someProperty(x) 否则什么都不做。
    • 我的想法是一样的,@LeeGunn
    • 正如@LeeGunn 所暗示的,在这种情况下,属性不只是一个setter 方法吗?我不明白。似乎是疏忽。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-21
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 2011-11-16
    • 2013-12-04
    相关资源
    最近更新 更多