C# ?? 属性 中的运算符,它是如何工作的?

C# ?? operator in property, how it works?

我不明白它是如何工作的。

private Person _user;

private Person User
{
  get
  {
    return _user ?? ( _user = GetUser() );
  }
}

我第一次引用用户 属性 时,_user 为空,所以它 returns ( _user = GetUser() )?????

我错过了什么?

首先,它是 null-coalescing operator,如果不是 null,则它 returns 是左手操作数,否则它是 returns 右手操作数。

return _user ?? ( _user = GetUser() );

_usernull 的情况下,它 returns 由 GetUser 方法返回的内容,并将私有字段也设置为它。

所以它的工作方式如下:

  1. GetUser returns 赋给 _user
  2. 的值
  3. 赋值表达式(_user = GetUser())returns的值。

参见:How assignment expression returns value.

它基本上首先检查 _user 是否不是 null。如果不为null returns 就可以了。否则,它将 _user 设置为 GetUser() returns.

伪代码

_user != null 
    return _user 
otherwise 
    _user = GetUser()

这里有一篇 post 讨论了 "Null Coalescing operator"

它被称为 Null Coalescing 运算符。如果它左侧的对象为空,它将执行右侧的表达式。

这里右边的运算符设置了_user对象,所以下次引用User时,就不再执行右边的操作了,return _user

赋值表达式 =_user 和 returns 赋值,因此它可以像表达式一样使用。

该代码与此基本相同:

private Person _user;

private Person User
{
    get
    {
        if (_user == null) _user = GetUser();
        return _user;
    }
}

工作原理

空合并运算符 (??) returns 如果对象不为空,则它 returns 运算符另一侧的任何对象。所以声明:

return _user ?? ( _user = GetUser() );

说,"return _user, unless it's null, in which case return the result of the assignment ( _user = GetUser() )"。这是为 _user 赋值并在同一行中返回赋值的巧妙方法。

话虽这么说,一些开发人员会争辩说我上面写的第一个方法,使用两行而不是一行,更易读(意图更清晰)并且更容易维护。

??是以下语法糖:

if(_user != null)
    return _user; // first part before ??
else
    return (_user = GetUser() ); //Second part after ??

编辑:

正如@Rufus L 指出的那样:

(_user = GetUser() );部分将GetUser的return值赋值给_user,然后returns赋给_user的值。如果我们简化前面的代码:

if(_user != null)
    return _user;
else
{
    _user = GetUser();
    return _user;
}

额外信息:你可以链式赋值,只要类型相同,或者实现隐式转换:

int x, y, z;
x = y = z = 4;

所以在 Habibs 提示之后,我在 MSDN 中找到了这个。 = Operator (C# Reference) 哪里清楚了...

"The assignment operator (=) stores the value of its right-hand operand in the storage location, property, or indexer denoted by its left-hand operand and returns the value as its result."

我仍然不敢相信我不知道。