Null check on XElement
Asked Answered
D

6

9

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.)

Dorwin answered 23/5, 2011 at 10:51 Comment(2)
Why do you want to avoid Extension Methods if that's exactly a use-case for them? Alternative (the Java-way) would be to define a static method somewhere, and use that: ElementHelper.ValueOrDefault(elem, "TagName", "").Oruro
@Marcel Jackwerth I just want to know whether there are other ways:)Dorwin
O
16

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.

Obtuse answered 23/5, 2011 at 10:58 Comment(3)
So - just to state it - the full solution would be (String)elem.Element("TagName") ?? "";.Oruro
Thanks! I think I'll stick with this solution.Dorwin
Great stuff, saves me doing a null check each time!Windsucking
H
7

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.

Houdini answered 23/5, 2011 at 10:52 Comment(4)
You didn't read the question. If elem.Element("TagName") != null, we need the elem.Element("TagName").Value, not elem.Element("TagName")Kyrstin
@Kyrstin - I reread it now. Still can't see what you are complaining about here. Can you please give some more information regarding what you mean is wrong here?Vi
Øyvind: The part after the : has an additional .Value. I stumbled into the same trap.Assuntaassur
@Kyrstin & @Assuntaassur - Didn't see that one. Fixed my answer now. Verified it on my own system.Vi
K
2

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.

Kyrstin answered 23/5, 2011 at 11:3 Comment(1)
I modified (improved?) this answer by removing the class constraint on the TResult type and returning default(TResult) instead of null.Aoudad
O
2

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.

Oruro answered 23/5, 2011 at 11:5 Comment(0)
A
0

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?

Assignable answered 13/10, 2019 at 20:40 Comment(0)
R
0

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.

Restless answered 20/7, 2020 at 15:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.