2014-01-22 60 views
0

我需要一个linq查询,查找基于名称值为“Foo”的XmlElementAttribute的对象的属性名称,如果不是,则只需指定名称的财产。因此,查询将返回属性名称的单个字符串,或者null都不存在这些条件。Linq反射查询按属性查找对象的属性名称

例子:

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

所以,如果我想找到“敏”,但是我给“富”,查询会先看看,如果发现物业设有XmlElementAttribute与“富”的名字。如果不是,那么匹配属性名称以找到“MyInt”。如果找不到“MyInt”,则该值为空。

这是我迄今(这是不正确):

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

显然更清洁的实现是值得欢迎的。

回答

0

我想通了。我先将它编入嵌套的foreach循环,然后Resharper将它转换为我。甜!

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;