Adam
Adam

Reputation: 4780

Linq Reflection Query to Lookup an Object's Property Name by Attribute

I need a linq query that looks up the property name of an object based on the XmlElementAttribute having a name value of "Foo" FIRST and if not, then just give the name of the property. So the query would return a single string of the property name or null neither of these criteria exist.

Example:

public class MyClass
{
   [XmlElement("Foo")]
   public int MyInt {get; set;}
   [XmlElement("FooString")]
   public string MyString {get; set;}
}

So if I wanted to find "MyInt" but I am given "Foo", the query would first see if it finds a property with an XmlElementAttribute with a name of "Foo". If not, then just match on the property names to find "MyInt". If "MyInt" can not be found, the value would be null.

Here is what I have so far (it's not correct):

var propertyName = targetObject.GetType().GetProperties()
   .Select(property => new {property, attributes = property.GetCustomAttributes(true)})
   .Where(@t => @t.attributes.Any())
   .SelectMany(@t => @t.attributes, (@t, attribute) => new {@t, attribute})
   .Where(@t => @t.attribute.GetType() == typeof(XmlElementAttribute))
   .Select(@t => @t);

Obviously cleaner implementations are welcome.

Upvotes: 0

Views: 1198

Answers (1)

Adam
Adam

Reputation: 4780

I figured it out. I coded it out in nested foreach loops first and Resharper converted it for me. Sweet!

var propertyName = (from property in targetObject.GetType().GetProperties() 
                                              let attributes = property.GetCustomAttributes(true) 
                                              where attributes.Any() 
                                              let xmlAttribute = attributes.Where(a => a.GetType() == typeof (XmlElementAttribute)).Select(a => a).FirstOrDefault() as XmlElementAttribute 
                                              where xmlAttribute != null && xmlAttribute.ElementName.EqualsIgnoreCase(salesforceXmlElement.LocalName)
                                              select property.Name).FirstOrDefault() ?? salesforceXmlElement.LocalName;

Upvotes: 1

Related Questions