12

Consider the following typical scenario:

if(myObject == null) {
    myObject = new myClass();
}

I'm wondering what is thought of the following replacement using the null-coalescing operator:

myObject = myObject ?? new myClass();

I'm not sure whether I should be using the second form. It seems like a nice shorthand, but the myObject = myObject construct at the beginning seems like it could be a bit of a code-smell.

Is this a reasonable thing to do, or is there a better shorthand that I am missing? Or maybe, "It's three lines, get over it!"?

Edit: As has been mentioned, perhaps calling this a typical scenario is something of an overstatement. I usually find that I encounter this situation when I'm retrieving an entity from a database that has a child reference type property that may or may not be populated yet:

myClass myObject = myClassService.getById(id);
myObject.myChildObject = myObject.myChildObject ?? new myChildClass();
9
  • 15
    Newbies believe things like this to be "hackish", more experienced devs just call it "idiomatic".
    – Doc Brown
    Aug 22, 2013 at 17:03
  • If the object looks like a value object ("has value semantics", in idiomatic speak), MyClass should provide a public static readonly member of a Empty value of its type. See String.Empty on MSDN.
    – rwong
    Aug 22, 2013 at 17:12
  • 2
  • 5
    Isn't there a ??= operator?
    – aviv
    Aug 22, 2013 at 17:43
  • 1
    @aviv I wish there was! Oct 11, 2013 at 1:08

4 Answers 4

16

I use the null coalescing operator all of the time. I like the conciseness of it.

I find this operator to be similar in nature to the ternary operator (A ? B : C). It takes a little practice before the reading of it is second nature, but once you're used to it I feel readability improves over the longhand versions.

Also, the situation you describe is only one scenario where the operator is useful. It's also handy to replace constructs like this:

if (value != null)
{
    return value;
}
else
{ 
    return otherValue;
}

or

return value != null ? value : otherValue;

with

return value ?? otherValue;
3
  • Definitely agree in general about using this operator. When I see references to using it, though, it's typically something like myObject = myObject2 ?? myObject3. What I'm wondering about specifically is using the operator to set an object to itself unless it's null.
    – grin0048
    Aug 22, 2013 at 16:46
  • 2
    I think the same reasoning applies in either case. It's a more concise way to express the same logic.
    – 17 of 26
    Aug 22, 2013 at 16:51
  • I remember looking at the IL for each of those three forms once. The first and the second were identical, but the third was optimized in a fashion as it could assume null was a comparison. Aug 22, 2013 at 19:35
2

What I'm wondering about specifically is using the operator to set an object to itself unless it's null.

The ?? operator is called the null-coalescing operator and is used to define a default value for nullable value types or reference types. It returns the left-hand operand if the operand is not null; otherwise it returns the right operand.

myObject = myObject ?? new myObject(); - instantiate default value of object

More details and code sample about null-coalescing operator - MSDN article.

If you check for more than nullable condition, as an alternative you may use Ternary operator.

Ternary operator

You may also look at ?: Operator. It is called Ternary or conditional operator. The conditional operator (?:) returns one of two values depending on the value of a Boolean expression.

A nullable type can contain a value, or it can be undefined. The ?? operator defines the default value to be returned when a nullable type is assigned to a non-nullable type. If you try to assign a nullable value type to a non-nullable value type without using the ?? operator, you will generate a compile-time error. If you use a cast, and the nullable value type is currently undefined, an InvalidOperationException exception will be thrown.

A code example from MSDN - ?: Operator (C# Reference):

int? input = Convert.ToInt32(Console.ReadLine());
string classify;

// ?: conditional operator.
classify = (input.HasValue) ? ((input < 0) ? "negative" : "positive") : "undefined";
2
  • So taking the example from the question and applying the conditional operator, we'd have something like myObject = (myObject == null) ? new myClass() : myObject. So, unless I'm missing a better usage of the conditional operator, it seems to have the same "problem" with setting an object to itself (if it's not null) as the null-coalescing operator--and it's less concise.
    – grin0048
    Aug 22, 2013 at 17:06
  • If you are checking for more than one condition (Not null and greater than zero) - then conditional operator will do it. However, just null checking would work for ?? operator.
    – Yusubov
    Aug 22, 2013 at 17:08
2

I don't think that scenario is (or at least should be) typical.

If you want the default value of some field not to be null, then set it in the field initializer:

myClass myObject = new myClass();

Or, if the initialization is more complicated, set it in the constructor.

If you want to create myClass only when you actually need it (e.g. because creating it takes a long time), then you can use Lazy<T>:

Lazy<myClass> myObject = new Lazy<myClass>();

(This calls the default constructor. If the initialization is more complicated, pass lambda that creates myClass to the Lazy<T> constructor.)

To access the value, use myObject.Value, which will call the initialization if this is the first time you're accessing myObject.Value.

3
  • IMO lazy creation is only useful if you are not guaranteed to need the resulting object, only time I use lazy creation is when I have a cashed derived result that I reset when something changes and I know that I'll need the same result a lot and the recalc is expensive. other wise I just don't want to bother with the null check Aug 22, 2013 at 23:47
  • @ratchetfreak Yes, that's why I suggested field initializer first.
    – svick
    Aug 22, 2013 at 23:52
  • There are other cases also. What I'm looking at at the moment: The first pass sets the exception cases. The second pass sets defaults for everything else. ??= would cut the line in half. Oct 11, 2013 at 1:10
1

I especially like using ?? in conjunction with optional method parameters. I limit the need for overloads and ensure the thing has a value.

public void DoSomething (MyClass thing1 = null) {
    thing1 = thing1 ?? new MyClass();
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.