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)
从 C# 8 开始,这可以通过Null-coalescing 赋值运算符实现
a ??= b;
Run Code Online (Sandbox Code Playgroud)
这只会分配b给a如果 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; }
如果你担心在一个语句中完成这一切,那你就不走运了 - 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()运算符.