【问题标题】:How to get Attribute Value in C# for the class property如何在 C# 中获取类属性的属性值
【发布时间】:2017-06-08 07:33:09
【问题描述】:
 [System.AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    sealed class ColumnName : Attribute
    {
        // See the attribute guidelines at 
        //  http://go.microsoft.com/fwlink/?LinkId=85236

        readonly string Column;

        // This is a positional argument
        public ColumnName(string columnName)
        {
            this.Column = columnName;
        }
    }

    public class Comment
    {
        [ColumnName("ID1")]
        public int Id;
        [ColumnName("NAME1")]
        public string Name;
        [ColumnName("TEST1")]
        public string Test;
    }

在此代码中,您可以看到我创建了一个具有属性 ColumnName 的类注释。 ColumnName 是我用来定义 attirubte 的自定义类。

现在我正在寻找一种解决方案来找到所有属性的 ColumnName 值。

public static List<T> ExecuteReader<T>(string str)
        {
            var res = typeof(T);

            return new List<T>();
        }

我尝试在我的问题上运行一些 Stack Overflow 代码,但效果不佳。我的代码中缺少什么?

【问题讨论】:

  • 你尝试了哪个代码?
  • @Fabiano 我又试了一次 typeof(T).GetProperties() return null
  • 在您的示例中,您没有属性,只有成员变量。将它们转换为属性或使用 typeof(T).GetMembers()
  • typeof(T).GetFields()(它们是字段)。 GetMembers() 将返回两个字段、属性、方法、事件……

标签: c# data-structures properties


【解决方案1】:

给定

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
public sealed class ColumnNameAttribute : Attribute
{
    public readonly string Column;

    public ColumnNameAttribute(string columnName)
    {
        this.Column = columnName;
    }
}

(按照惯例,属性的名称应该以Attribute 结尾,并注意我已将AttributeTargets 限制为Propertyes 和Fields)你可以

public static class ColumnsCache<T>
{
    public static readonly IReadOnlyDictionary<MemberInfo, string> Columns = BuildColumnsDictionary();

    public static Dictionary<MemberInfo, string> BuildColumnsDictionary()
    {
        var dict = new Dictionary<MemberInfo, string>();

        var members = typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Instance)
            .Where(x => x.MemberType == MemberTypes.Field || x.MemberType == MemberTypes.Property);

        foreach (MemberInfo member in members)
        {
            var attr = member.GetCustomAttribute<ColumnNameAttribute>(true);

            if (attr != null)
            {
                dict.Add(member, attr.Column);
            }
        }

        return dict;
    }
}

(注意技巧:我们通过使用通用静态类来缓存列名列表(以及具有ColumnNameAttribute 的字段/属性)。.NET 运行时将创建各种不同的ColumnsCache&lt;T1&gt;、@ 987654329@、ColumnsCache&lt;T3&gt;,每个都有不同的列字典)

那你就可以了

var cols = ColumnsCache<Comment>.Columns;
var colNames = cols.Values;

cols 变量将引用字典 MemberInfo -> string(列名),而colNames 是一个只有列名的IEnumerable&lt;string&gt;。如果你想通过MemberInfo 使用反射,你必须检查MemberInfoFieldInfo 还是PropertyInfo,将其转换并使用FieldInfoPropertyInfo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 2023-03-03
    • 2015-06-18
    相关资源
    最近更新 更多