Lambda表达式 - 它是否正确评估?

时间:2012-08-25 18:24:45

标签: c# .net linq custom-attributes

我有以下代码似乎没有正确行事。有一个属性有一个属性不是FieldMapAttribute类型的属性,但它仍然进入if条件,我检查匹配该类型属性的计数。

foreach (PropertyInfo _property in _properties)
{
    var attributes = _property.GetCustomAttributes(false);
    if (attributes.Select(a => a.GetType() == typeof(FieldMapAttribute)).Count() > 0)
    {
        colname = (attributes.Select(a => a.GetType() == typeof(FieldMapAttribute)).Cast<FieldMapAttribute>().First()).DbColumnName;
    }
}

有人可以帮我理解这里发生了什么吗?

2 个答案:

答案 0 :(得分:5)

假设你要做的是检查属性上是否存在FieldMapAttribute属性,你应该使用

var attributes = _property.GetCustomAttributes(typeof(FieldMapAttribute), false);
if (attributes.Length > 0)
{
    ...
}

另一种选择是使用

if (attributes.OfType<FieldMapAttribute>().Any())

您应该注意使用Select的方式不正确。 Select用于将元素投影到新表单中。您的Select语句会返回bools的列表 - 该属性的每个属性都有一个(任何属性,而不仅仅是FieldMapAttribute类型)。这意味着,如果您的财产看起来像这样

[SomeAttribute]
[SomeOtherAttribute]
[FieldMapAttribute]
public string MyProp { get; set; }

然后你的select语句将产生以下结果

false
false
true

如您所见,在此结果集上调用Count将始终返回属性上设置的自定义属性的数量(同样,任何属性)。

希望这有帮助。

答案 1 :(得分:2)

无论您当前的代码究竟发生了什么,我觉得它可以更简单地写成更多

foreach (PropertyInfo property in properties)
{
    if (property.IsDefined(typeof(FieldMapAttribute), false))
    {
        colName = property.GetCustomAttributes(typeof(FieldMapAttribute), false)
                          .Cast<FieldMapAttribute>()
                          .First()
                          .DbColumnName;            
    }
}

(请注意,最终将使用 last 属性将属性定义为指定列名称的属性。这是您想要的吗?)

甚至使用LINQ来完成整个事情:

var attrType = typeof(FieldMapAttribute);
var attr = properties.SelectMany(p => p.GetCustomAttributes(attrType), false)
                     .Cast<FieldMapAttribute>()
                     .FirstOrDefault();
if (attr != null)
{
    colName = attr.DbColumnName;
}