2012-08-25 108 views
0

我有以下代碼似乎沒有正確行事。有一個屬性有一個不屬於FieldMapAttribute類型的屬性,但它仍會進入if條件,在此條件下我將檢查與該類型屬性匹配的計數。Lambda Expression - 它的評估是否正確?

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

有人能幫我理解這裏發生了什麼嗎?

回答

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總是返回定製的數在屬性上設置的屬性(再次,任何屬性)。

希望這會有所幫助。

+0

@Downvoter謹慎解釋你的downvote? –

+1

不是我的失望,但PropertyInfo.IsDefined是一個更簡單的測試方法。 –

+0

這兩個答案都非常有幫助,我真的很感激Jon&Adi。感謝球員,我似乎再次順利運行。 –

2

不管到底發生了什麼對你當前的代碼,它看起來對我來說,它可以寫成更簡單地說:

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

(請注意,這將結束與最後財產。定義屬性作爲一個指定的列名是你想要的)

甚至使用LINQ整個事情:

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

我喜歡這種方法,但是在定義了'FieldMapAttribute'的情況下,這不會導致查找屬性的屬性兩次而不是一次? –

+0

@AdiLester:可能(儘管不在第二種選擇中)。除非我有理由認爲這確實是一個瓶頸,否則我不會擔心。 –

+0

感謝喬恩......我感謝你的回覆和幫助。 :) –