The C# ?? null coalescing operator (and using it with LINQ)

One of the subtle (but cool) language features of C# is the ?? "null coalescing" operator.  This provides a nice, terse way to check whether a value is null, and if so return an alternate value.

Simple Example Usages

Several folks have blogged about the ?? operator in the past - read here, here, here, and here for some previous examples on how to use it.  Simply put, the ?? operator checks whether the value provided on the left side of the expression is null, and if so it returns an alternate value indicated by the right side of the expression.  If the value provided on the left side of the expression isn't null, then it returns the original value. 

For example, let's assume we have a string variable "message".  We could check whether message was null, and return an alternate value using the code below:

Because the "message" variable above wasn't null, the "result" variable is assigned the original "hello world" message value. 

In the code snippet below, however, message is a null value, and so the ?? operator will return the alternate value we've provided:

The ?? operator works for both reference types and value types.  For example, below we are checking whether the nullable integer "number" variable is null.  Because it isn't, the result will be the original value (55):

If "number" is null, then result is assigned the value 0:

Using the ?? operator with LINQ

Last month I wrote a blog post that covered using the new LINQ to XML support in .NET 3.5.  One of the "gotchas" you often need to deal with when handling raw XML are cases where XML shapes are irregular and/or missing elements/attributes.  The ?? operator can be very useful in these scenarios.

For example, let's consider a scenario where we have an XML file or feed with the following contact data:

We could write the below LINQ to XML code in C# to open the XML file and retrieve back a sequence of anonymous type objects with "Name", "Title", "Email" and "YearsAtCompany" properties, and then databind the results to an <asp:gridview> control on a page:

Notice above how I'm using the explicit conversion operator support on the XElement class to retrieve strongly typed values from the XML.  This enables me to just cast the c.Element("YearsAtCompany") value to an int - and it will then automatically convert the string value to an integer for me, and type the "YearsAtCompany" property on my anonymous type to be an int.

When we run the above code snippet, we'll then get a nice Gridview listing of our contacts:

 

This explicit conversion support works great when the <YearsAtCompany> element is always defined.  But it will throw a runtime error in the case where we have a <Contact> that is missing a <YearsAtCompany> sub-element:

One way to fix this is to modify our LINQ to XML query so that we indicate that YearsAtCompany is a nullable integer.  We can do this by changing the explicit cast to be (int?) instead of (int):

This enables our query to execute cleanly and not raise any errors.  Instead a null value will be assigned to the YearsAtCompany property if no <YearsAtCompany> element is present in the XML. 

When we run the application and databind the results to the Gridview, you can see the YearsAtCompany column for our third contact is empty as a result (since the value is null):

But what if we didn't want a missing XML value to result in a null integer value - but instead just indicate a value of 0? 

Well.... that is where we can use the new ?? operator support.  We can just modify the LINQ to XML query like below to indicate a default value of 0 if no element is present:

This indicates that if the <YearsAtCompany> element is missing in the XML, and the result would otherwise be null, instead assign a value of 0.  Notice in the intellisense above how C# automatically detects that this means that the YearsAtCompany property on the new anonymous type will never be null - and so it marks the property to be of type (int) instead of (int?). 

And now when we run the page we'll see a value of 0 show up in our third row instead of a blank value:

Summary

You can use the C# ?? operator in all types of scenarios.  Hopefully the LINQ to XML scenario above provides some interesting food for thought on how you can use it with any LINQ scenario (including LINQ to SQL, LINQ to XML, LINQ to Objects, LINQ to SharePoint, etc).  

Hope this helps,

Scott

34 Comments

  • Very nice stuff Scott.

    Keep it up :)

    Chris

  • It is (and your link already "proves" it) not a new feature with VS 2008, it is already in .net 2.0

  • Hi !
    It's just to tell that the ?? operator already exists in C# 2.0 it was added with the nullable types.
    It's a very useful opertor nonetheless, and it's good to make a refresher for those who missed it !

  • sadly this doesn't work:
    return someObject as String ?? throw new NullReferenceException();

  • Lars/Skup,

    >>>>> It's just to tell that the ?? operator already exists in C# 2.0 it was added with the nullable types.

    Embarassingly, I goofed when saying it was new in C# 3.0. It is indeed in C# 2.0 (the releases unfortunately blur on me sometimes).

    But at least being able to use it with LINQ (the main topic of this post) is all new. ;-)

    Thanks,

    Scott

  • Yes it is a great way of converting nullable value types to non-nullable types and control the default value. I love the operator, and the blank look on beginners faces when I describe it as the "Null coalescing operator" - although the name is descriptive ;-)

    It is also worth pointing out that because it evaluates the expression to the right, you can chain them up like such:
    string item = DBValue ?? ConfigValue ?? "SomeOtherValue";

    I often use it like this to configure a properties value from a database, and if null from web.config, and if null from an inline value. All this can be done from a single line in an easy to read form.

    When using it with strings you still have the same issue of having both EMPTY strings and NULL strings. If one of the values is an empty string rather than null, it will return an empty string.

    Maybe you could use an extension method, which converts an empty string into NULL so you could write something like this?

    string item = DBValue.Nullify() ?? ConfigValue.Nullify() ?? "SomeOtherValue";

    Regards,

    David

  • Hi,

    Any chance of seeing something like this for VB?

    Regards
    Jeremy

  • Scott, As always, great stuff. I know the difference is subtle, but wouldn't this be a better way to write you final code example. You are casting to a nullable type when the value assigned to YearsAtCompany will never be null.

    YearsAtCompany = (int)(c.Element("YearsAtCompany") ?? 0)

    -Andy

  • Earlier this week I started adding the ?? operator all through the code I am currently working on. It is simply amazing. That is an amazing trick to use it with LINQ. I am certain I'll use that a great deal.

    Thanks for the great trick.

  • Any chance us lonely VB guys will get a ?? operator?

  • Hi Andrew,

    >>>>>>> I know the difference is subtle, but wouldn't this be a better way to write you final code example. You are casting to a nullable type when the value assigned to YearsAtCompany will never be null. YearsAtCompany = (int)(c.Element("YearsAtCompany") ?? 0)

    Unfortunately you can't use that approach (it will give a compile error). The reason is because c.Element("YearsAtCompany") returns a XElement object, and not an integer - so you can't use it with the ?? 0 operator.

    What you could write is the following:

    YearsAtCompany = (int)((int?) c.Element("YearsAtCompany") ?? 0)

    This makes the final (int) assignment a little more explicit - but I think complicates the expression. That is why I just did:

    YearsAtCompany = (int?) c.Element("YearsAtCompany") ?? 0

    Which I think is simpler.

    Hope this helps,

    Scott

  • Hi Jeremy/Pvong,

    >>>>>> Any chance of seeing something like this for VB?

    I have a blog post coming up soon on the new LINQ to XML Literal support in VB (which is wickedly cool). I think you'll like what you'll see.

    Thanks,

    Scott

  • The C# ?? null coalescing operator was already on C# 2.0!! What's different now?

  • Holy Cow,
    That's a pretty cool shortcut, now more extra typing for checking null. I am definitelly all about writing more clear code and with the ?? operation my code will definitelly look cleaner, at least to people wo actually knows what the operaror does

    Thanks for the heads up scott.

  • I have found the new language features to be fantastic.

    One issue that I ran into when using LINQ to XML was that often you want to run nested operations.

    For example, consider the following XML.


    Daniel
    Crabtree



    Using similar code to example in your article, where c in a descendant of "Contact".
    I may want to write things like c.Element("Name").Element("FirstName"), to get the first name value.

    The problem I ran into was, what is the Name element does not exist?
    You cannot use the null coalescing operator.

    My solution is to use a new feature of C# 3.0, extension methods.

    I made extension methods for element (eg. ElementN) and other XML types that internally used the null coalescing operator.
    The extension methods return a new element, that contains nothing - effectively a null element.

    Now I can make a call like (string?)c.ElementN("Name").Element("FirstName") ?? "Unknown First Name".
    Without having to worry that the first call to element may return null, producing an exception.

    An obvious alternative to this, that I often use, is to construct XPath queries instead.
    However, I have not considered efficiency yet, does anyone know if XPath queries are much less efficient than using Descendants/Element, etc?

    Also, perhaps there is something built in already to support this that I do not know about.
    I'm wondering if anyone had a better solution?

  • Hi David,

    If you are using C# 3.0, you could write Nullify() as an extension method for strings and then you should be set using the syntax you displayed:


    string item = DBValue.Nullify() ?? ConfigValue.Nullify() ?? "SomeOtherValue";


    On C# 2.0, I guess we're stuck with the way it is now.

    John

  • Scott,
    I know this comment is offtopic, but Phil Haack mentioned this on his blog as reason for moving to Microsoft. I hope that you can post some overview posts about new ASP.NET MVC framework?

  • I love the ?? operator!
    One of the real pains with the old DataSet Designer is that the Row properties generated are not nullable types. So the DBNull is not converted into a Null. So you can't use ?? on those properties. You have to call IsXxxNull - yuck. LinqToSql is much better in this respect.

    The DataSet Designer in VS2008 has had a number of nice improvements - does it now support emitting nullable types for row properties?

  • Nice!, thanks a lot, i guess when we are using (int?)e.Element("YearsAtCompany") ?? 0, do we need to have (int?) cause we are already having a default value by ?? 0. In that case , what is the problem with (int)e.Element("YearsAtCompany") ?? 0

  • thanks for the post. But I Have been using this C sharp 2.0 for long with nullable type. Is there something new that I am missing?

  • Great entry. Never heard of the ?? operator before but will for sure use it from now on.
    Thanks for pointing it out again.

  • I like this tip. send more please.

  • Nice article Scott

    Is there a way to apply NumberFormat to decimals where I am assigning to the AskingPrice or does the formatting have to be done elsewhere, i.e. in the listview databind?

    var r = from p in i.Properties
    orderby p.AskingPrice ascending
    select new
    {
    AskingPrice = (decimal?)p.AskingPrice ?? 0,
    };

  • Good entry. Never heard of the ?? operator before, but definitely looks useful. Thanks for the tip.

  • Personally, I don't use ?? very much; I still tend to use the old style ( xxx==null?xxx:"foo"; ) out of habit, though it's a nice little operator. The bit that really peeves me is DBNull.Value - whoever invented that should be SHOT because we now have to write code to convert between that abomination and null (probably to cope with VB not really understanding the concept of null coherently, or maybe someone on the SQL dev team who didn't like null parameters?).

    int foo = parameter == null || parameter.Equals(DBNull.Value) ? "0" : (int)parameter;
    instead of int foo = parameter ?? 0;

    Any way that something could be done without breaking existing code; for example, overriding the == operator on DBNull.Value (easy) and modifying the way in which the implementation of the (null)== operator so that it matched DBNull.Value? Although this would break _some_ code, I'd imagine that the number of times that (real world) you want to distinguish between (null) and DBNull.Value could be counted on the fingers of one hand; and there are much large compatibility issues than that between 2.0 and 3.5 code, so provided it were well publicised it wouldn't add any significant effort to porting a 2.0 app to 3.5.

    BTW - it's very nice having an ORM built into the framework :), though it'll put me out of a job!

  • is there a way to easily apply it to work with DBNull.Value ?

  • Hi Daniel,

    >>>>> I may want to write things like c.Element("Name").Element("FirstName"), to get the first name value. The problem I ran into was, what is the Name element does not exist?

    I believe one way to fix this would be to use the c.Decendents("FirstName") method. This will return null if the "Name" element doesn't exist. This way you could use the ?? operator to handle this.

    Hope this helps,

    Scott

  • Hi Dragan,

    >>>> I know this comment is offtopic, but Phil Haack mentioned this on his blog as reason for moving to Microsoft. I hope that you can post some overview posts about new ASP.NET MVC framework?

    I'll be posting more about the new ASP.NET MVC framework in the weeks ahead.

    Thanks,

    Scott

  • Hi Scott,
    Its very nice post, but I will like to point it out that mistakenly your are leaking few imoprtant emailid's in your sample code:), Why don't you use, some not "that" important emailid, like I am doing currently in this comment
    Happy coding
    Dhananjay123@hotmail.com

  • I like it and love LINQ.
    No more SqlDataReaders, DataAdapters, DataSets etc, etc, etc...
    Just like it should be always.
    Thank you for making me more happy!

    Mariusz

  • Nice article, I wasn't aware of the "??"-operator yet, and have seen alot of "dirty hacks" around it. This will make my code so much more cleaner, thanks!

  • >> Hi,
    >> Any chance of seeing something like this for VB?
    >> Regards
    >> Jeremy

    That is the one more disadvantage why VB.NET is a "poor" language. The one more thing that makes me very sad, that VB.NET does not have short conditional statement, like ?: in C++/C#. The weak implementation IIF, does not work properly in some cases.
    The following code will cause an null reference exception

    Dim SomeOptionalValue As String
    ...
    IIF(SomeOptionalValue Is Nothing, "NONE", SomeOptionalValue.ToUpper())

    As far IIF a function SomeOptionalValue.ToUpper() of it and it will be calculation all the time before IIF is called.

    Unlike, C# works code fine

    String SomeOptionalValue = Null
    ...
    SomeOptionalValue == Null? "NONE", SomeOptionalValue.ToUpper();

  • Hello,

    Is this possible in VB.NET to? Where can I find some info on it?

    Thank You,
    Miguel

  • >The one more thing that makes me very sad, that VB.NET does not have short conditional statement, like ?: in C++/C#. The weak implementation IIF, does not work properly in some cases.
    Use the new If ternary operator. It works exactly like C# one.
    If(SomeOptionalValue Is Nothing, "NONE", SomeOptionalValue.ToUpper())

Comments have been disabled for this content.