在linq查询中设置和使用值

时间:2013-01-14 12:51:38

标签: c# .net linq

我正在过滤PropertyInfo列表,如下所示:

foreach (PropertyInfo propertyInfo in 
            ClassUtils.GetProperties(patternType).
            Where(pi => pi.GetCustomAttribute<TemplateParamAttribute>() != null).
            OrderBy(pi1 => pi1.GetCustomAttribute<TemplateParamAttribute>().Order))
{
    TemplateParamAttribute attr = propertyInfo.GetCustomAttribute<TemplateParamAttribute>();
...

这可以正常工作,但在每次迭代中我都不满意3 GetCustomAttribute次调用。有没有办法减少GetCustomAttribute次呼叫(并仍然使用linq)?

5 个答案:

答案 0 :(得分:3)

  

有没有办法减少GetCustomAttribute调用次数(仍然使用linq)?

绝对 - 尽早进行投射。为了便于阅读,我会在一个在 foreach循环之前声明的查询中执行此操作:

var query = from property in ClassUtils.GetProperties(patternType)
            let attribute = property.GetCustomAttribute<TemplateParamAttribute>()
            where attribute != null
            orderby attribute.Order
            select new { property, attribute };

foreach (var result in query)
{
    // Use result.attribute and result.property
}

答案 1 :(得分:1)

您可以使用以下查询,它使用声明匿名类型的let关键字。

var select = from propertyInfo in typeof (ClassUtils).GetProperties(patternType)
             let attr = propertyInfo.GetCustomAttribute<TemplateParamAttribute>()
             where attr != null
             orderby attr.Order
             select propertyInfo;
foreach (var propertyInfo in select)
{
    //Operate
}

答案 2 :(得分:1)

怎么样:

foreach(TemplateParamAttribute attr in
    ClassUtils.GetProperties(patternType).
        Select(pi => pi.GetCustomAttribute<TemplateParamAttribute()).
        Where(pa => pa != null).
        OrderBy(pa.Order))
 {
      // Use attr
 }

如果您需要访问循环中的属性和属性,可以执行以下操作:

foreach(var info in
    ClassUtils.GetProperties(patternType).
        Select(pi => new {prop = pi, attr = pi.GetCustomAttribute<TemplateParamAttribute()}).
        Where(pia => pia.attr != null).
        OrderBy(pia.attr.Order))
 {
      // Use info.prop and info.attr
 }

答案 3 :(得分:0)

如果您对GetCustomAttribute对象使用propertyInfo以外的任何内容:

foreach (TemplateParamAttribute attr in ClassUtils.GetProperties(patternType)
    .Select(pi => pi.GetCustomAttribute<TemplateParamAttribute>())
    .Where(a => a != null)
    .OrderBy(a => a.Order))
{
}

答案 4 :(得分:0)

要避免多次GetCustomAttribut次调用,您可以为查询引入新的范围变量tpa。此外,如果您只需要循环中的属性,那么获取自定义属性并迭代它们:

var attributes = from pi in ClassUtils.GetProperties(patternType)
                 let tpa = pi.GetCustomAttribute<TemplateParamAttribute>()
                 where tpa != null 
                 orderby tpa.Order
                 select tpa;

foreach(TemplateParamAttribute attr in attributes)
{
    // ...
}