c# shorthand for if not null then assign value
Asked Answered
S

6

41

Is there any shorthand in c# now that will cutdown the following code:

var testVar1 = checkObject();
if (testVar1 != null)
{
      testVar2 = testVar1;
}

In this situation only want to assign testVar2 if testVar1 is not null from the CheckObject() result (testVar2 has a setter that will fire off code). Was trying to think how could use the null coalesce stuff but not really working out.

Adding on to this testVar2 has code on it's setter to fire, so do not want testVar2 being set to anything if the value is null.

    public MyObj testVar2
    {
        get { return _testVar2; }
        set
        {
            _testVar2 = value;
            RunSomeCode();                
        }
    }
Skepticism answered 6/6, 2019 at 21:58 Comment(4)
testVar2 = testVar1 ?? testVar2;; means it will set testVar2 to testVar1 if its not null, if it is null it will set testVar2 to testVar2. Example: dotnetfiddle.net/hUPYDURecency
testVar2 = testVar1 != null ? testVar1 : testVar2;Tasiatasiana
I get that, if testVar1 is null though I dont want testVar2 being set to anything at all as even if it's set to itself it will hit the setter method.Skepticism
Now that I see avoiding the setter was a primary goal, there is an additional suggestion. I think after that though, we are out of syntactic sugarzArchitectural
A
41

There are a couple!

The ternary operator:

testvar2 = testVar1 != null ? testvar1 : testvar2;

Would be exactly the same logic.

Or, as commented you can use the null coalescing operator:

testVar2 = testVar1 ?? testVar2

(although now that's been commented as well)

Or a third option: Write a method once and use it how you like:

public static class CheckIt
{
    public static void SetWhenNotNull(string mightBeNull,ref string notNullable)
    {
        if (mightBeNull != null)
        {
            notNullable = mightBeNull;
        }
    }
}  

And call it:

CheckIt.SetWhenNotNull(test1, ref test2);
Architectural answered 6/6, 2019 at 22:5 Comment(5)
What do you expect that function to do exactly?Buttonball
@Buttonball it wasn't exactly right, but fixed now and sets test2 to test1 if test1 has a value. (while not using the set method if the value is null for test1)Architectural
I believe this function should be called SetUnlessNull(), because the assignment happens when the first argument is not null.Sudduth
@Sudduth completely fair!Architectural
null coalescing operator method isn't valid here. That'd only work if testVar1 "IS" null, not "IS NOT" null.Mountaineer
J
32

NOT the answer for the question, but I googled "c# shorthand set if null" and first landed here, so just for others. The question was "shorthand for if NOT null then assign value", the following is "shorthand for if null then assign value".

In C# 8.0+ you can use ??=:

// Assign testVar1 to testVar2, if testVar2 is null
testVar2 ??= testVar1;

// Which is the same as:
testVar2 = testVar2 ?? testVar1;

// Which is the same as:
if(testVar2 == null)
{
   testVar2 = testVar1;
}

And my favorite:

// Create new instance if null:
testVar1 ??= new testClass1();

// Or even (if the variable type is already known):
testVar1 ??= new();

// Which is the same as:
if(testVar1 == null)
{
   testVar1 = new testClass1();
}

Just an example which I use very often:

List<string> testList = null;

// Add new test value (create new list, if it's null, to avoid null reference)
public void AddTestValue(string testValue)
{
   testList ??= new List<string>();
   testList.Add(testValue);
}
Jenniejennifer answered 21/5, 2020 at 22:10 Comment(10)
Is the first comment line correct "// Assign to testVar1, if testVar2 is null" - or should it be "Assign to testVar2, if testVar2 is null"? The verbose 3rd example assigns testVar1 to testVar2 if testVar2 is null.Ebbarta
@Ebbarta It should be correct, A ??= B means assign to B, but only if the source (A) is null, otherwise keep the value. "Assign to testVar2, if testVar2 is null" makes no sense 😉 testVar2 is null or it has a value, so "Assign to testVar2, if testVar2 is null" wouldn't change anything. See my last example, I guess this is more clear, you assign to a new list, if the list is null. Imagine it in a loop or something, so before the first item will be added, you create a new list, for the other items you use the existing list (because testList is NOT null and no new list will be created).Jenniejennifer
You can go one step further with that last example: (testList ??= new List<string>()).Add(testValue); The brackets return the value assigned to testList.Gingerly
Oh yeah, that's right, this should be the shortest way ;)Jenniejennifer
+1 for making use of example to create an object if null, this is not mentioned a lot elsewhere, and it is my favorite as well!Wearisome
This does not answer what the question here asking.Lowis
See the disclaimer (my second sentence), this is for people who google "c# shorthand set if null", because THIS thread is the first result. But I edited to make it a bit clearer.Jenniejennifer
Thank you very much. However, the title of this question is "shorthand for if not null then assign", which clearly shows that it is not what you are looking for.Lowis
I think your favorite can now be written as testVar1 ??= new()', even shorter.Madcap
Yap, that's true 🙂.Jenniejennifer
R
2

You could use the null-coalescing operator, which would look like this: testVar2 = testVar1 ?? testVar2. You can replace ?? testVar2 with whatever you want to set it to if testVar1 is null.

Refectory answered 6/6, 2019 at 22:6 Comment(2)
+1 Your answer is a little bit short and confusing, but the docu link brought me to the answer that fits best for me testVar2 ??= testVar1.Islamite
The question was "IS NOT" null, not "IS" null so using ?? (or ??=) is invalid here.Mountaineer
U
2

You mention that testVar2 has a setter that fires off some event when it gets set. If you aren't checking that testVar2 is being set to itself the event will still fire using the null coalescing operator (or the ternary operator).

I think you'll either have to check for testVar2 being set to itself in its setter, or do what you're doing now.

    public MyObj testVar2
    {
        get { return _testVar2; }
        set
        {
            if (_testVar2 != value)
            {
               _testVar2 = value;
               RunSomeCode();
            }                
        }
    }

I reckon this is totally my opinion but I would leave it how you have it now. I think it communicates the intent better than the short hand.

testVar2 = testVar1 ?? tesrVar2 says, "set testVar2 to testVar1. Unless testVar1 is null. Then set testVar2 to testVar2".

if (testVar1 != null)
{
   testVar2 = testVar1;
}

says, "if testVar1 is not null, set testVar2 to testVar1".

Ursuline answered 6/6, 2019 at 22:12 Comment(0)
C
1

If you never want to allow testVar2 to be set to null, then it probably makes more sense to check for null in the setter itself. Otherwise you have to remember to check for null anytime you try to set it.

Note that I also modified the casing to conform to C# standards

private MyObj testVar2;

public MyObj TestVar2
{
    get { return testVar2; }
    set
    {
        if (value == null) return;      // Or throw an ArgumentNullException
        if (testVar2 == value) return;  // No need to RunSomeCode if the value isn't changing

        testVar2 = value;
        RunSomeCode();                
    }
}

Now, if your concern is still to check for null before setting the property (if, for example, you decided to throw an exception in the case of a null value), then there's nothing wrong with your original code (the ternary/null-coalescing solutions seem "wasteful" somehow, in that they may set something to itself), and you can do it in one line:

if (testVar1 != null) SomeClass.TestVar2 = testVar1;

If, however, you're only creating testVar1 in order to capture the result of the call to CheckObject(), then the null-coalescing operator makes a little more sense because you don't have to create a variable to store the value:

SomeClass.TestVar2 = CheckObject() ?? SomeClass.TestVar2;
Ceil answered 6/6, 2019 at 22:28 Comment(0)
T
0

In C# 9 property patterns were introduced allowing checking for a non-null object with the following variable assignment:

if (checkObject() is { } testVar1)
{
      testVar2 = testVar1;
}

Technically you can also check for a concrete type as null will not be recognized as a valid type, but the former approach is generally recommended for a null check:

if (checkObject() is string testVar1)
{
      testVar2 = testVar1;
}
Talithatalk answered 7/5 at 7:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.