C#属性中的自定义属性

5

我有一个类的属性集合,我想循环遍历每个属性。每个属性可能有自定义属性,因此我想循环遍历这些自定义属性。在这种特殊情况下,我的City类上有一个自定义属性,如下所示:

public class City
{   
    [ColumnName("OtroID")]
    public int CityID { get; set; }
    [Required(ErrorMessage = "Please Specify a City Name")]
    public string CityName { get; set; }
}

该属性被定义为:
[AttributeUsage(AttributeTargets.All)]
public class ColumnName : System.Attribute
{
    public readonly string ColumnMapName;
    public ColumnName(string _ColumnName)
    {
        this.ColumnMapName= _ColumnName;
    }
}

当我尝试循环遍历属性[这个循环正常工作],然后循环遍历属性时,它只忽略了属性的for循环,并且没有返回任何内容。
foreach (PropertyInfo Property in PropCollection)
//Loop through the collection of properties
//This is important as this is how we match columns and Properties
{
    System.Attribute[] attrs = 
        System.Attribute.GetCustomAttributes(typeof(T));
    foreach (System.Attribute attr in attrs)
    {
        if (attr is ColumnName)
        {
            ColumnName a = (ColumnName)attr;
            var x = string.Format("{1} Maps to {0}", 
                Property.Name, a.ColumnMapName);
        }
    }
}

当我进入具有自定义属性的立即窗口时,我可以执行以下操作:

?Property.GetCustomAttributes(true)[0]

它将返回ColumnMapName: "OtroID"

但我似乎无法通过编程使其正常工作


1
顺便提一下:按照惯例,属性类应该被称为 ColumnNameAttribute - Heinzi
3
仅出于好奇,typeof(T) 中的 T 是什么?在即时窗口中,您调用了 Property.GetCustomAttribute(true)[0],但在 foreach 循环内部,您却在类型参数上调用 GetCustomattributes。 - Dr. Andrew Burnett-Thompson
1
@Dr.AndrewBurnett-Thompson,在这种情况下,泛型T是我的City类。我正在编写一个工具,将通用存储库映射到一端的类和另一端的数据库。很好的观点,我以为我已经在那里了,但我改成了 Object[] attrs = Property.GetCustomAttributes(true); foreach (var attr in attrs) 现在它完美地工作 :) - Jordan
@Jordan 太好了!很高兴它起作用了。我本来应该把它作为答案的,但没关系 ;) - Dr. Andrew Burnett-Thompson
@Dr.AndrewBurnett-Thompson,请将其作为答案发布;这就是我还没有选择最佳答案的原因。如果您这样做,我会很乐意选择它! - Jordan
显示剩余2条评论
4个回答

8
我相信你想要做的是这样的:

你想要做什么:

PropertyInfo[] propCollection = type.GetProperties();
foreach (PropertyInfo property in propCollection)
{
    foreach (var attribute in property.GetCustomAttributes(true))
    {
        if (attribute is ColumnName)
        {
        }
    }
}

3

我得到了这段代码,最终使变量x的值为"OtroID 映射到 CityID"

var props = typeof(City).GetProperties();
foreach (var prop in props)
{
    var attributes = Attribute.GetCustomAttributes(prop);
    foreach (var attribute in attributes)
    {
        if (attribute is ColumnName)
        {
            ColumnName a = (ColumnName)attribute;
            var x = string.Format("{1} Maps to {0}",prop.Name,a.ColumnMapName);
        }
    }
}

3

在作者的要求下,从原问题的评论转载

仅仅出于兴趣,typeof(T)中的T代表什么?

在立即窗口中,您正在调用Property.GetCustomAttribute(true)[0],但在foreach循环内部,您正在调用TypeParameter上的GetCustomattributes。

这一行:

System.Attribute[] attrs = System.Attribute.GetCustomAttributes(typeof(T));

应该是这样的:

应该是这样的

System.Attribute[] attrs = property.GetCustomAttributes(true);

最好的问候,

1
在内部查看中,您应该调查属性而不是 typeof(T)。
使用智能感知并查看可以从 Property 对象调用的方法。
Property.GetCustomAttributes(Boolean) 可能对您很重要。 这将返回一个数组,您可以在其中使用 LINQ 快速返回与您要求匹配的所有属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接