Assignment operation that does nothing if variable is null?
if you're concerned about doing this all in a single statement, you're out of luck - C# doesn't have this functionality at the linguistic level and doesn't support operator declaration (as does F#) or overloading of the assignment operator (as does C++). There are, however, a couple of options, if none quite as elegant as you requested.
The if
statement, as you mentioned, though it can be written as a single line
if(a == null) a = b;
A helper method which uses a ref
parameter
public void AssignIfNull<T>(ref T target, T value)
{
if(target == null) target = value;
}
// ...
AssignIfNull(ref a, b);
Note the above will not work with a Property, since they cannot be passed as a ref
parameter.
EDIT: While the above is similar to Interlocked.CompareExchange
, such an alternative returns the original value of the first parameter, so it may prove more of a gotcha than implementing the above method.
Or you could carefully rewrite your initial statement to use a null-coalescing (??
) operator in the initial assignment.
Updated
Since C# 8 this is possible with the Null-coalescing assignment operator
a ??= b;
This will only assign b
to a
if a
is null
Original Answer
Although the syntax is verbose
(a is null?()=>a=b:(Action)(()=>{}))();
Let's break it apart
( // 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!
Anyway I would just use the one liner if if(a is null) { a = b; }
As you said, an if
statement is what you need. There is no conditional operator that doesn't assign when null
. An if
is most suitable in this case (not everything has to be a oneliner).
The best options:
if(a == null)
{
a = b;
}
Or:
a = a ?? b;
In fact, I believe that the latter is optimized away as a simple if
statement.
Assigning a
to itself isn't bad. With object references, it is just an assignment of the memory address. For value types, this is just a little chunk of data.
If a
is actually a property setter, check inside the setter the value has changes:
private string a;
public string A
{
get
{
return a;
}
set
{
if (value != a)
{
a = value;
}
}
}