Using C# null coalescing operator ?? with LINQ to Xml

By Indranil Chatterjee

The C# null coalescing operator ?? provides a convenient way to return default values when the expression on its left evaluates to null. One such case is LINQ to Xml if we need to return default values for missing nodes/attributes. This example shows an example.

The C# null coalescing operator takes two expressions as its two operands. If the expression on the left evaluates to null, then it returns the value of the expression on its right, else it returns the value of the expression on its left.

In the example below, since message is assigned with a non-null value, the result variable is assigned with its original value “Hello world”.

string message = "Hello world";
string result = message ?? "Empty string";
//output: result == "Hello world"

However, in the following example, since the nullable integer variable age is assigned to null, the value that gets assigned to resultAge is the value 0 from the right hand side of the ?? operator.

int? age = null;
int? resultAge = age ?? 0;
//output: resultAge == 0

We often need to read Xml files and load them into objects. Let’s consider the following Xml file XMLFile1.xml:

<?xml version="1.0" encoding="utf-8" ?>
<Employees>
<Employee>
<
Name>Indranil</Name>
<
Age>36</Age>
<
Title>Soln Architect</Title>
</Employee>
<Employee>
<
Name>Anindita</Name>
<
Age>35</Age>
<
Title>Tech Architect</Title>
</Employee>
<Employee>
<
Name>John</Name>
<
Age>36</Age>
<
Title>Manager</Title>
</Employee>
</Employees>

This can be loaded into a list of employee objects using the following LINQ to Xml code:

var res = XDocument.Load("XMLFile1.xml")
.
Descendants("Employee")
.Select(e =>
new
{
Name = (string)e.Element("Name"),
Age = (int)e.Element("Age"),
Title = (string)e.Element("Title")
});

This works fine when all nodes are present. In case any one of them is optional (Let’s say the node Title), then the above code will throw a runtime exception. In order to avoid that and also to return a default value for Title element (e.g. in case we want to bind this result to some front end control), we can use the null coalescing operator as shown below:

var res = XDocument.Load("XMLFile1.xml")
.
Descendants("Employee")
.Select(e =>
new
{
Name = (string)e.Element("Name"),
Age = (int)e.Element("Age"),
Title = (string)e.Element("Title") ?? "Unknown" //Prints out the string "Unknown in case Title element is not present in the file
});

This code will even work well with the following xml content:

<?xml version="1.0" encoding="utf-8" ?>
<Employees>
<Employee>
<Name>Indranil</Name>
<Age>36</Age>
<Title>Soln Architect</Title>
</Employee>
<Employee>
<Name>Anindita</Name>
<Age>35</Age>
<Title>Tech Architect</Title>
</Employee>
<Employee>
<Name>John</Name>
<Age>36</Age>

</Employee>
</Employees>

If we print out the nodes as follows:

Console.WriteLine("Employees:");
res.
ToList().ForEach(e =>
{
Console.WriteLine("Name: {0}, Age: {1}, Title: {2}", e.Name, e.Age, e.Title);
});

The value of Title for employee John is printed out as "Unknown" to the console.

Using C# null coalescing operator ?? with LINQ to Xml  (1710 Views)