17

Is there an easier/better way to return a default value if a XAttribute on a XElement is not existing?:

I'm trying to write this in a shorter way (cause it's a two-liner):

var a = root.Attribute("testAttribute");
var v = (a == null ? "" : a.Value);

My approach: via an extension method:

public static XAttribute Attribute(this XElement obj, string name, string defaultValue)
{
    if (obj.Attribute(name) == null)
        return new XAttribute(name, defaultValue);
    return obj.Attribute(name);
}

var v = root.Attribute("testAttribute", "").Value;

Will this have any side-effects like a massive negative speed impact ? Is there any better way to do that?

Mike
  • 339
  • 1
  • 4
  • 9

2 Answers2

26

There's a much easier way to do that:

var v = (string) root.Attribute("testAttribute") ?? "";

The explicit conversion from XAttribute to string returns null if the input XAttribute is null. The null-coalescing operator then effectively supplies the default value of an empty string.

Of course, you can still write your extension method, but I'd do it in terms of the above. I'd also change the name parameter to be of type XName instead of string, for more flexibility.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • +1. The `System.Xml.Linq` namespace makes extensive use of implicit conversions which is not obvious, since intellisense does not reveal them. – Olivier Jacot-Descombes Dec 06 '12 at 16:11
  • Worth noting, with C#6 you can also do `var v = root.Attribute("testAttribute")?.Value ?? "";` – Khale_Kitha Jul 29 '16 at 20:18
  • @Khale_Kitha: You can, but I think I'd still do the cast. Aside from anything else, that approach works when casting to other nullable types. – Jon Skeet Jul 30 '16 at 10:39
0

I needed a similar thing in my project. I created a custom attribute

[AttributeUsage(AttributeTargets.Property)]
public class DefaultValue : Attribute
{
 public string ElementName {get; set;}
 public string AttributeName {get; set;}
 public object DefaultValue {get; set;}

public object GetValue(XElement element)
{
  var v = root.Attribute(AttributeName);
 if(v!= null)
  return v.value;
 else
  return DefaultValue
}
}

I used this attribute over all the properties with similar usage

[DefaultValue(ElementName="elementName",AttributeName="attri",DefaultValue="Name")]
public string Prop{get; set;}

I get the value by invoking a method of this attribute

var attribute = propertyInfo.GetCustomAttribute(typeof(DefaultValue),false);
var value = attribute.GetValue(element);

Hope this helps

Akanksha Gaur
  • 2,636
  • 3
  • 26
  • 50