2017-06-08 114 views
0
[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的自定义类。如何在C#中获得类属性的属性值

现在我正在寻找一种溶剂来查找所有属性的ColumnName值。

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

      return new List<T>(); 
     } 

我试着在我的问题上运行一些堆栈溢出代码,但它不能正常工作。我的代码中缺少什么东西?

+0

你试过了哪些代码? – Fabiano

+3

可能重复[反射 - 获取属性名称和属性值](https://stackoverflow.com/questions/6637679/reflection-get-attribute-name-and-value-on-property) – Fabiano

+0

@Fabiano我试过再次typeof(T).GProProperties()返回null – Adrian

回答

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结尾的名称,请注意,我限制了AttributeTargetsProperty ES和Field)你可以

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<T1>ColumnsCache<T2>ColumnsCache<T3>,每一个与不同的字典列)

然后可以

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

cols变量将引用字典MemberInfo - >string(式柱名),而colNamesIEnumerable<string>只有列名称。如果你想用MemberInfo反射,你必须检查MemberInfoFieldInfo还是PropertyInfo,然后使用FieldInfoPropertyInfo