我有以下代码似乎没有正确行事。有一个属性有一个属性不是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;
}
}
有人可以帮我理解这里发生了什么吗?
答案 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;
}