An assignment operation that does nothing if the variable is zero?

I want to conditionally assign a value to a variable if this variable is already null . Also, if this variable does not yet exist null , I want nothing , and I want to be able to do everything with a single statement.

 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 
+6
source share
6 answers

if you are worried that all this is done in one statement, you are out of luck - C # does not have this function at the linguistic level and does not support operator declaration (like F #) or overloading an assignment operator (like C ++). However, there are several options if they are not as elegant as you requested.

The if , as you mentioned, although it can be written as a single line

 if(a == null) a = b; 

Helper method that uses the ref parameter

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

Please note that the above will not work with Property, since they cannot be passed as a ref parameter.

EDIT: although the above is similar to Interlocked.CompareExchange , such an alternative returns the original value of the first parameter, so it may be more than the implementation of the above method.

Or you can carefully rewrite your original statement to use the zero coalescence operator ( ?? ) in the original assignment.

+7
source

As you said, an if is what you need. There is no conditional statement that is not assigned when null . In this case, if is most appropriate (not everything should be oneliner).

The best options:

 if(a == null) { a = b; } 

Or:

 a = a ?? b; 

In fact, I believe the latter is optimized as a simple if .

Appointment a for yourself is not bad. With object references, this is just a memory address assignment. For value types, this is just a small piece of data.

If a is actually a property setter, check inside the setting, the value has changes:

 private string a; public string A { get { return a; } set { if (value != a) { a = value; } } } 
+3
source

Although the syntax is verbose

 (a is null?()=>a=b:(Action)(()=>{}))(); 

Let it break it into pieces

 ( // 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! 

In any case, I would use one insert if if(a is null) { a = b; } if(a is null) { a = b; } if(a is null) { a = b; } if(a is null) { a = b; }

+3
source

When I first encountered this situation, I decided to check my code, where I understand this. I tend to have two solutions, both of which are related to the null coalescing operator.

Case 1: Initialization. Using your values ​​above, this will be:

 object a = null ?? something; 

Obviously, I would not write this line of code (resharper will complain if nothing else). But this is the essence of what is happening. If I have two (or more) values ​​available when creating a , I write it like this:

Case 2: Never install a , but use ?? when a is used. In this case, the code will look like this:

 MethodTakingA(a ?? b); 

If there are several method calls or other places where I will need to use ?? then this is a bad idea.

There is a third case when I perform an exact task that you avoid. That is, when one of the parameters of my method can be null, and I have a default value for use in this case (as opposed to throwing an ArgumentNullException ). Here is an example:

 public void Foo(string str) { str = str ?? String.Empty; //Use str as needed below without fear that it might be null. } 

I would like to get a better answer for this case, but of course I do not write code where it is advisable to optimize this purpose, and the theoretical answer

 string localStr = str ?? String.Empty; 

Just adds a new variable to add it. Otherwise, I have nothing to do, so I maintain my self-name and live with it.

+2
source

As one operator,

 var result = ((a == null) ? (a = b) : null); 

The result value can be discarded. Having a and b as the properties of the object, and adding Console.WriteLine() in the setting for a will show that it is only assigned when it was previously null.

The only thing that stops him is that he is completely clean is that the result variable is created; hopefully it's still clean enough.


Addition. I just realized that you can also use:

 var result = a ?? (a = b); 

as an even shorter version above. Again, a = b is evaluated only when a null .

+1
source

I think the new feature that came with C # 8.0 makes this pretty easy. Are there any new ones ?? = operator , which check the variable and, if it is zero, set the value, if not, than nothing.

 if (variable is null) { variable = expression; } 

just doing like

 variable ??= expression; 

in your case it is:

 a ??= b; 
0
source

Source: https://habr.com/ru/post/1208364/


All Articles