类成员的自定义属性

cco*_*ook 8 c# reflection attributes custom-attributes

我正在使用自定义属性来定义类的成员如何映射到属性以作为表单发布(支付网关)发布.我有自定义属性工作正常,并能够通过"名称"获取属性,但希望成员本身获取属性.

例如:

getFieldName("name");
Run Code Online (Sandbox Code Playgroud)

VS

getFieldName(obj.Name);
Run Code Online (Sandbox Code Playgroud)

计划是编写一个方法,将带有成员的类序列化为一个postable字符串.

这是我此时的测试代码,其中ret是一个字符串,PropertyMapping是自定义属性:

foreach (MemberInfo i in (typeof(CustomClass)).GetMember("Name"))
{
    foreach (object at in i.GetCustomAttributes(true))
    {
        PropertyMapping map = at as PropertyMapping;
        if (map != null)
        {
            ret += map.FieldName;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Joh*_*ren 9

你不能真的这样做,除非你使用的是C#3.0,在这种情况下你需要依赖LINQ(ehm,表达式树).

你所做的是为lambda表达式创建一个虚方法,让编译器生成表达式树(编译器进行类型检查).然后你挖掘那棵树来获得成员.像这样:

static FieldInfo GetField<TType, TMemberType>(
    Expression<Func<TType, TMemberType>> accessor)
{
    var member = accessor.Body as MemberExpression;
    if (member != null)
    {
        return member.Member as FieldInfo;
    }
    return null; // or throw exception...
}
Run Code Online (Sandbox Code Playgroud)

鉴于以下课程:

class MyClass
{
    public int a;
}
Run Code Online (Sandbox Code Playgroud)

你可以得到这样的元数据:

// get FieldInfo of member 'a' in class 'MyClass'
var f = GetField((MyClass c) => c.a); 
Run Code Online (Sandbox Code Playgroud)

通过引用该字段,您可以按常规方式挖掘任何属性.即反思.

static TAttribute GetAttribute<TAttribute>( 
    this MemberInfo member ) where TAttribute: Attribute
{
    return member.GetCustomAttributes( typeof( TAttribute ), false )
        .Cast<TAttribute>().FirstOrDefault<TAttribute>();
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以通过编译器大量检查的内容在任何字段上挖掘属性.它也适用于重构,如果你重命名'一个'Visual Studio将捕获它.

var attr = GetField((MyClass c) => c.a).GetAttribute<DisplayNameAttribute>();
Console.WriteLine(attr.DisplayName);
Run Code Online (Sandbox Code Playgroud)

那里的代码中没有单个文字字符串.