【问题标题】:Lambda Expression - is it evaluating correctly?Lambda 表达式 - 它的评估是否正确?
【发布时间】:2012-08-25 18:24:44
【问题描述】:

我有以下代码似乎不正确。有一个属性具有一个不属于 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;
    }
}

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

【问题讨论】:

    标签: c# .net linq custom-attributes


    【解决方案1】:

    假设您要做的是检查属性上是否存在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 将始终返回在属性上设置的自定义属性的数量(同样,任何属性)。

    希望这会有所帮助。

    【讨论】:

    • 不是我的反对意见,但 PropertyInfo.IsDefined 是一种更简单的测试方法。
    • 两个答案都非常有帮助,我非常感谢 Jon 和 Adi。谢谢大家,我似乎又运行得很顺利了。
    【解决方案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;
    }
    

    【讨论】:

    • 我喜欢这种方法,但这不会导致在定义 FieldMapAttribute 的情况下查找属性的属性两次而不是一次吗?
    • @AdiLester:有可能(虽然不在第二个选项中)。除非我有任何理由认为这实际上是一个瓶颈,否则我不会担心。
    • 谢谢乔恩...感谢您的回复和帮助。 :)
    • 乔恩我不得不对你的建议做些小改动才能让它发挥作用。 colname = (_property.GetCustomAttributes(typeof(FieldMapAttribute), false).Cast().First()).DbColumnName;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 2010-09-09
    • 1970-01-01
    • 2014-08-05
    • 2022-10-15
    • 1970-01-01
    相关资源
    最近更新 更多