赋值操作如果变量为null则不执行任何操作?

LCI*_*III 6 c# variable-assignment c#-4.0

如果该变量已经存在,我想有条件地为变量赋值null.此外,如果该变量尚未null我想没有什么发生,我希望能够用一个单一的运营商做的一切.

object a = null;
object b = new Something();

// this is essentially what I want but done with an operator:
if(a == null)
{
    a = b;
}

// this is all I feel I have to work with,
a = a || b;
a = a ?? b;
a = a == null ? b : a;

// the above methods all end up performing a = a if a is not null
Run Code Online (Sandbox Code Playgroud)

Car*_*ñoz 7

更新

从 C# 8 开始,这可以通过Null-coalescing 赋值运算符实现

a ??= b;
Run Code Online (Sandbox Code Playgroud)

这只会分配ba如果 a 是null

原答案

虽然语法很冗长

(a is null?()=>a=b:(Action)(()=>{}))();
Run Code Online (Sandbox Code Playgroud)

让我们把它分开

(                           // Expression starts here
    a is null               // If a == null...
        ? () => a = b       // return lambda that assigns a = b
        : (Action) (        // Else return next lambda casted as Action
            () => {}        // Empty lambda that does nothing
        )                   // End cast
)                           // Expression ends here
();                         // Execute it!
Run Code Online (Sandbox Code Playgroud)

无论如何,如果 if(a is null) { a = b; }

  • 我肯定会做一个如果,但为了完整起见,我不得不发布答案 (3认同)
  • 为什么投反对票?这正是 OP 所要求的 (2认同)
  • 我没有投反对票,但这只是做“if”的一种晦涩的方式。事实上,`?` 就是这样做的。 (2认同)

Dav*_*vid 7

如果你担心在一个语句中完成这一切,那你就不走运了 - C#在语言层面没有这个功能,并且不支持操作员声明(如F#)或赋值运算符的重载(与C++一样).但是,有一些选项,如果没有你想要的优雅.

if正如您所提到的那样,该声明虽然可以写成一行

if(a == null) a = b;
Run Code Online (Sandbox Code Playgroud)

一个使用ref参数的辅助方法

public void AssignIfNull<T>(ref T target, T value)
{
    if(target == null) target = value;
}

// ...

AssignIfNull(ref a, b);
Run Code Online (Sandbox Code Playgroud)

请注意,上述内容不适用于Property,因为它们不能作为ref参数传递.

编辑:虽然上面的类似Interlocked.CompareExchange,但这样的替代方案返回第一个参数的原始值,因此它可能比实现上述方法更多的问题.

或者您可以仔细重写初始语句,以??在初始赋值中使用null-coalescing()运算符.