Iterating over class properties using LINQ

≯℡__Kan透↙ 提交于 2019-12-23 09:33:54

问题


There is a ParsedTemplate class that it has over 300 property (typed Details and BlockDetails). The parsedTemplate object will be fill by a function. After filling this object I need a LINQ (or other way) to find is there any property like "body" or "img" where IsExist=false and Priority="high".

public class Details
{
    public bool IsExist { get; set; }
    public string Priority { get; set; }
}

public class BlockDetails : Details
{
    public string Block { get; set; }
}

public class ParsedTemplate
{
    public BlockDetails body { get; set; }
    public BlockDetails a { get; set; }
    public Details img { get; set; }
    ...
}

回答1:


You're going to need to write your own method to make this appetizing. Fortunately, it doesn't need to be long. Something like:

static IEnumerable<Details> GetDetails(ParsedTemplate parsedTemplate)
{
    return from p in typeof(ParsedTemplate).GetProperties()
           where typeof(Details).IsAssignableFrom(p.PropertyType)
           select (Details)p.GetValue(parsedTemplate, null);
}

You could then, if you wanted to check if any property "exists" on a ParsedTemplate object, for example, use LINQ:

var existingDetails = from d in GetDetails(parsedTemplate)
                      where d.IsExist
                      select d;



回答2:


If you really wanted to use linq while doing that, you could try something like that:

bool isMatching = (from prop in typeof(ParsedTemplate).GetProperties()
                   where typeof(Details).IsAssignableFrom(prop.PropertyType)
                   let val = (Details)prop.GetValue(parsedTemplate, null) 
                   where val != null && !val.IsExist && val.Priority == "high"
                   select val).Any();

Works on my machine.

Or in extension method syntax:

isMatching = typeof(ParsedTemplate).GetProperties()
                 .Where(prop => typeof(Details).IsAssignableFrom(prop.PropertyType))
                 .Select(prop => (Details)prop.GetValue(parsedTemplate, null))
                 .Where(val => val != null && !val.IsExist && val.Priority == "high")
                 .Any();



回答3:


Use c# reflection. For example:

ParsedTemplate obj;
PropertyInfo pi = obj.GetType().GetProperty("img");
Details value = (Details)(pi.GetValue(obj, null));
if(value.IsExist)
{
   //Do something
}

I haven't compile but i think it work.




回答4:


        ParsedTemplate tpl = null;
        // tpl initialization
        typeof(ParsedTemplate).GetProperties()
            .Where(p => new [] { "name", "img" }.Contains(p.Name))
            .Where(p => 
                {
                    Details d = (Details)p.GetValue(tpl, null) as Details;
                    return d != null && !d.IsExist && d.Priority == "high"
                });


来源:https://stackoverflow.com/questions/11033198/iterating-over-class-properties-using-linq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!