如何在C#中为类属性

时间:2017-06-08 07:33:10

标签: c# data-structures properties

 [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的自定义类。

现在我正在寻找一个sollution来查找所有属性的ColumnName值。

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

            return new List<T>();
        }

我尝试在我的问题上运行一些Stack Overflow代码,但它不能正常工作。我的代码中缺少什么东西?

1 个答案:

答案 0 :(得分:2)

鉴于

[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限制为Property es和Field s)可以

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运行时将创建各种不同的{{1 },ColumnsCache<T1>ColumnsCache<T2>,每个都有不同的列字典

然后你可以

ColumnsCache<T3>

var cols = ColumnsCache<Comment>.Columns; var colNames = cols.Values; 变量将引用字典cols - &gt; MemberInfo(列名称),而string是仅包含列名称的colNames。如果您想使用IEnumerable<string>的反射,则必须检查MemberInfoMemberInfo还是FieldInfo,然后将其投射并使用PropertyInfoFieldInfo