Unique ways to use the null coalescing operator

C#Coding StyleNullConditional OperatorNull Coalescing-Operator

C# Problem Overview


I know the standard way of using the null coalescing operator in C# is to set default values.

string nobody = null;
string somebody = "Bob Saget";
string anybody = "";

anybody = nobody   ?? "Mr. T"; // Returns Mr. T
anybody = somebody ?? "Mr. T"; // Returns "Bob Saget"

But what else can ?? be used for? It doesn't seem as useful as the ternary operator, apart from being more concise and easier to read than:

nobody = null;
anybody = nobody == null ? "Bob Saget" : nobody; // Returns Bob Saget

So given that fewer even know about null coalescing operator...

  • Have you used ?? for something else?

  • Is ?? necessary, or should you just use the ternary operator (that most are familiar with)

C# Solutions


Solution 1 - C#

Well, first of all, it's much easier to chain than the standard ternary operator:

string anybody = parm1 ?? localDefault ?? globalDefault;

vs.

string anyboby = (parm1 != null) ? parm1
               : ((localDefault != null) ? localDefault
               : globalDefault);

It also works well if a null-possible object isn't a variable:

string anybody = Parameters["Name"]
              ?? Settings["Name"]
              ?? GlobalSetting["Name"];

vs.

string anybody = (Parameters["Name"] != null ? Parameters["Name"]
                 : (Settings["Name"] != null) ? Settings["Name"]
                 :  GlobalSetting["Name"];

Solution 2 - C#

I've used it as a lazy load one-liner:

public MyClass LazyProp
{
    get { return lazyField ?? (lazyField = new MyClass()); }
}

Readable? Decide for yourself.

Solution 3 - C#

I've found it useful in two "slightly odd" ways:

  • As an alternative for having an out parameter when writing TryParse routines (i.e. return the null value if parsing fails)
  • As a "don't know" representation for comparisons

The latter needs a little bit more information. Typically when you create a comparison with multiple elements, you need to see whether the first part of the comparison (e.g. age) gives a definitive answer, then the next part (e.g. name) only if the first part didn't help. Using the null coalescing operator means you can write pretty simple comparisons (whether for ordering or equality). For example, using a couple of helper classes in MiscUtil:

public int Compare(Person p1, Person p2)
{
    return PartialComparer.Compare(p1.Age, p2.Age)
        ?? PartialComparer.Compare(p1.Name, p2.Name)
        ?? PartialComparer.Compare(p1.Salary, p2.Salary)
        ?? 0;
}

Admittedly I now have ProjectionComparer in MiscUtil, along with some extensions, which make this kind of thing even easier - but it's still neat.

The same can be done for checking for reference equality (or nullity) at the start of implementing Equals.

Solution 4 - C#

Another advantage is that the ternary operator requires a double evaluation or a temporary variable.

Consider this, for instance:

string result = MyMethod() ?? "default value";

while with the ternary operator you are left with either:

string result = (MyMethod () != null ? MyMethod () : "default value");

which calls MyMethod twice, or:

string methodResult = MyMethod ();
string result = (methodResult != null ? methodResult : "default value");

Either way, the null coalescing operator is cleaner and, I guess, more efficient.

Solution 5 - C#

Another thing to consider is that the coalesce operator doesn't call the get method of a property twice, as the ternary does.

So there are scenarios where you shouldn't use the ternary operator, for example:

public class A
{
    var count = 0;
    private int? _prop = null;
    public int? Prop
    {
        get 
        {
            ++count;
            return _prop
        }
        set
        {
            _prop = value;
        }
    }
}

If you use:

var a = new A();
var b = a.Prop == null ? 0 : a.Prop;

the getter will be called twice and the count variable will be equal to 2, and if you use:

var b = a.Prop ?? 0

the count variable will be equal to 1, as it should.

Solution 6 - C#

The biggest advantage that I find to the ?? operator is that you can easily convert nullable value types to non-nullable types:

int? test = null;
var result = test ?? 0; // 'result' is int, not int?

I frequently use this in LINQ queries:

Dictionary<int, int?> PurchaseQuantities;
// PurchaseQuantities populated via ASP .NET MVC form.
var totalPurchased = PurchaseQuantities.Sum(kvp => kvp.Value ?? 0);
// totalPurchased is int, not int?

Solution 7 - C#

I've used ?? in my implementation of IDataErrorInfo:

public string Error
{
    get
    {
        return this["Name"] ?? this["Address"] ?? this["Phone"];
    }
}

public string this[string columnName]
{
    get { ... }
}

If any individual property is in an "error" state I get that error, and otherwise I get null. It works really well.

Solution 8 - C#

You can use the null coalescing operator to make it a bit cleaner to handle the case where an optional parameter is not set:

public void Method(Arg arg = null)
{
    arg = arg ?? Arg.Default;
    ...

Solution 9 - C#

I like to use the null coalesce operator to lazy load certain properties.

A very simple (and contrived) example just to illustrate my point:

public class StackOverflow
{
    private IEnumerable<string> _definitions;
    public IEnumerable<string> Definitions
    {
        get
        {
            return _definitions ?? (
                _definitions = new List<string>
                {
                    "definition 1",
                    "definition 2",
                    "definition 3"
                }
            );
        }
    } 
}

Solution 10 - C#

One thing I've been doing a lot lately is using null coalescing for backups to as. For example:

object boxed = 4;
int i = (boxed as int?) ?? 99;

Console.WriteLine(i); // Prints 4

It's also useful for backing up long chains of ?. that could each fail

int result = MyObj?.Prop?.Foo?.Val ?? 4;
string other = (MyObj?.Prop?.Foo?.Name as string)?.ToLower() ?? "not there";

Solution 11 - C#

> Is ?? necessary, or should you just use the ternary operator (that most are familiar with)

Actually, my experience is that all too few people are familiar with the ternary operator (or more correctly, the conditional operator; ?: is "ternary" in the same sense that || is binary or + is either unary or binary; it does however happen to be the only ternary operator in many languages), so at least in that limited sample, your statement fails right there.

Also, as mentioned before, there is one major situation when the null coalescing operator is very useful, and that is whenever the expression to be evaluated has any side effects at all. In that case, you cannot use the conditional operator without either (a) introducing a temporary variable, or (b) changing the actual logic of the application. (b) is clearly not appropriate in any circumstances, and while it's a personal preference, I don't like cluttering up the declaration scope with lots of extraneous, even if short-lived, variables, so (a) is out too in that particular scenario.

Of course, if you need to do multiple checks on the result, the conditional operator, or a set of if blocks, are probably the tool for the job. But for simple "if this is null, use that, otherwise use it", the null coalescing operator ?? is perfect.

Solution 12 - C#

The only problem is the null-coalesce operator doesn't detect empty strings.


I.e.

string result1 = string.empty ?? "dead code!";

string result2 = null ?? "coalesced!";
Output

> result1 = "" >
> result2 = coalesced!


I'm currently looking into overriding the ?? operator to work around this. It sure would be handy to have this built into the framework.

Solution 13 - C#

> Is ?? necessary, or should you just use the ternary operator (that most are familiar with)

You should use what best expresses your intent. Since there is a null coalesce operator, use it.

On the other hand, since it's so specialized, I don't think it has other uses. I would have preferred an appropriate overload of the || operator, as other languages do. This would be more parsimonious in the language design. But well …

Solution 14 - C#

Cool! Count me as someone who didn't know about the null coalescing operator -- that's pretty nifty stuff.

I find it much easier to read than the ternary operator.

The first place that comes to mind where I might use it is to keep all of my default parameters in a single place.

public void someMethod(object parm2, ArrayList parm3)
{
  someMethod(null, parm2, parm3);
}

public void someMethod(string parm1, ArrayList parm3)
{
  someMethod(parm1, null, parm3);
}

public void someMethod(string parm1, object parm2)
{
  someMethod(parm1, parm2, null);
}

public void someMethod(string parm1)
{
  someMethod(parm1, null, null);
}

public void someMethod(object parm2)
{
  someMethod(null, parm2, null);
}

public void someMethod(ArrayList parm3)
{
  someMethod(null, null, parm3);
}

public void someMethod(string parm1, object parm2, ArrayList parm3)
{
  // Set your default parameters here rather than scattered 
  // through the above function overloads
  parm1 = parm1 ?? "Default User Name";
  parm2 = parm2 ?? GetCurrentUserObj();
  parm3 = parm3 ?? DefaultCustomerList;

  // Do the rest of the stuff here
}

Solution 15 - C#

It is a bit of a weird use case, but I had a method where an IDisposable object is potentially passed as an argument (and therefore disposed by the parent), but it could also be null (and so should be created and disposed in a local method)

To use it, the code either looked like

Channel channel;
Authentication authentication;

if (entities == null)
{
	using (entities = Entities.GetEntities())
	{
		channel = entities.GetChannelById(googleShoppingChannelCredential.ChannelId);
		[...]
	}
}
else
{
	channel = entities.GetChannelById(googleShoppingChannelCredential.ChannelId);
	[...]
}

But with a null coalesce it becomes much neater:

using (entities ?? Entities.GetEntities())
{
	channel = entities.GetChannelById(googleShoppingChannelCredential.ChannelId);
	[...]
}

Solution 16 - C#

I have used it like this:

for (int i = 0; i < result.Count; i++)
{
    object[] atom = result[i];

    atom[3] = atom[3] ?? 0;
    atom[4] = atom[4] != null ? "Test" : string.Empty;
    atom[5] = atom[5] ?? "";
    atom[6] = atom[6] ?? "";
    atom[7] = atom[7] ?? "";
    atom[8] = atom[8] ?? "";
    atom[9] = atom[9] ?? "";
    atom[10] = atom[10] ?? "";
    atom[12] = atom[12] ?? false;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArmstrongestView Question on Stackoverflow
Solution 1 - C#James CurranView Answer on Stackoverflow
Solution 2 - C#Cristian LibardoView Answer on Stackoverflow
Solution 3 - C#Jon SkeetView Answer on Stackoverflow
Solution 4 - C#Mario CossiView Answer on Stackoverflow
Solution 5 - C#Fabio LimaView Answer on Stackoverflow
Solution 6 - C#RyanView Answer on Stackoverflow
Solution 7 - C#Matt HamiltonView Answer on Stackoverflow
Solution 8 - C#Niall ConnaughtonView Answer on Stackoverflow
Solution 9 - C#mlnycView Answer on Stackoverflow
Solution 10 - C#Blue0500View Answer on Stackoverflow
Solution 11 - C#userView Answer on Stackoverflow
Solution 12 - C#whatispunkView Answer on Stackoverflow
Solution 13 - C#Konrad RudolphView Answer on Stackoverflow
Solution 14 - C#HanClintoView Answer on Stackoverflow
Solution 15 - C#PaulGView Answer on Stackoverflow
Solution 16 - C#Muhammad AwaisView Answer on Stackoverflow