lazymf
lazymf

Reputation: 355

Null check on XElement

My current project (C# 3.5) has a lot of code like this (elem is an instance of XElement):

textbox1.Text = elem.Element("TagName") == null ? "" : elem.Element("TagName").Value;

Is there any way to write the same thing without repeating a call elem.Element() and without use of extension methods? Maybe using lambdas? (But I cannot figure out how.)

Upvotes: 9

Views: 17340

Answers (6)

iinuwa
iinuwa

Reputation: 627

This doesn't apply to the original question, but since it seems this question is still actively viewed, this is an update for C# 6.0+ projects:

Since C# 6.0, using the null-conditional operator (?.) and null-coalescing operator (??) you can do this:

textbox1.Text = elem.Element("TagName")?.Value ?? "";

Cf. Null-Conditional Operator Documentation and Null-Coalescing Operator Documentation.

Upvotes: 0

user10555044
user10555044

Reputation:

Have a similar situation to this which has to do with Xml boolean checks and this was my resolution that used the null coalescing operator:

Convert.ToBoolean(this.xDocument.Root.XPathSelectElement(@"/settings/checkbox[@name = 'MessageArrivedTimeCheckBox']").Value ?? "false");

The reason being that the xml is understood by default as a string with there being type resolution issues that may be resolvable through serialization parameters within the xml itself, but I doubt even that would be possible because it doesn't understand it until runtime. Maybe there's a declaration or assignment that can be done with the element itself with type expectation?

Upvotes: 0

Øyvind Bråthen
Øyvind Bråthen

Reputation: 60694

Yes. you can write it like this:

(string)elem.Element("TagName") ?? "";

This is the null coalescing operator.

It means that if the left hand side is not null, then use the left hand side. If it is null, then use the right hand side.

Upvotes: 7

aL3891
aL3891

Reputation: 6275

XElement has a explicit conversion to String (and a bunch of other types) that will actually call .Value. In otherwords you can write this:

var value = (String)elem.Element("TagName");

i think this will return null if the actual element is null as well

-edit-

verified, here is an example:

 var x = new XElement("EmptyElement");
 var n = (String)x.Element("NonExsistingElement");

n will be null after this.

Upvotes: 16

Marcel Jackwerth
Marcel Jackwerth

Reputation: 54762

A crazy ?? approach:

// make this a member-variable somewhere
var emptyElement = XElement.Parse("<x></x>");

(elem.Element("TagName") ?? emptyElement).Value;

Would have preferred an extension method though.

Upvotes: 2

VMAtm
VMAtm

Reputation: 28355

There is a great article on the CodeProject for such actions: http://www.codeproject.com/KB/cs/maybemonads.aspx

public static TResult With<TInput, TResult>(this TInput o, 
       Func<TInput, TResult> evaluator)
       where TResult : class where TInput : class
{
  if (o == null) return null;
  return evaluator(o);
}

string valueEl = this.With(x => elem.Element("TagName")
                  .With(x => x.Value);

Other examples are available on the CodeProject.

Upvotes: 2

Related Questions