[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代码,但它不能正常工作。我的代码中缺少什么东西?
答案 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>
的反射,则必须检查MemberInfo
是MemberInfo
还是FieldInfo
,然后将其投射并使用PropertyInfo
或FieldInfo
。