问题描述
我正在使用自定义属性来定义如何将类的成员映射到属性以作为表单发布(支付网关)发布.我的自定义属性工作得很好,并且能够通过名称"获取属性,但想通过成员本身获取属性.
I am using a Custom Attribute to define how a class's members are mapped to properties for posting as a form post (Payment Gateway). I have the custom attribute working just fine, and am able to get the attribute by "name", but would like to get the attribute by the member itself.
例如:
getFieldName("name");
对
getFieldName(obj.Name);
计划是编写一个方法,将具有成员的类序列化为可发布的字符串.
The plan is to write a method to serialize the class with members into a postable string.
这是我此时的测试代码,其中 ret 是一个字符串,PropertyMapping 是自定义属性:
Here's the test code I have at this point, where ret is a string and PropertyMapping is the custom attribute:
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;
}
}
}
提前致谢!
推荐答案
你不能真正做到这一点,除非你使用的是 C# 3.0,在这种情况下你需要依赖 LINQ(嗯,表达式树).
You can't really do this, unless you're using C# 3.0 in which case you'll need to rely on LINQ (ehm, expression trees).
您所做的是为 lambda 表达式创建一个虚拟方法,让编译器生成表达式树(编译器进行类型检查).然后你深入那棵树来获取成员.像这样:
What you do is that you create a dummy method for a lambda expression which lets the compiler generate the expression tree (compiler does the type checking). Then you dig into that tree to get the member. Like so:
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...
}
给定以下类:
class MyClass
{
public int a;
}
你可以这样获取元数据:
You can get the meta data like this:
// get FieldInfo of member 'a' in class 'MyClass'
var f = GetField((MyClass c) => c.a);
通过对该字段的引用,您可以按照通常的方式挖掘任何属性.即反射.
With a reference to that field you can then dig up any attribute the usual way. i.e. reflection.
static TAttribute GetAttribute<TAttribute>(
this MemberInfo member ) where TAttribute: Attribute
{
return member.GetCustomAttributes( typeof( TAttribute ), false )
.Cast<TAttribute>().FirstOrDefault<TAttribute>();
}
现在您可以通过编译器大量检查的内容来挖掘任何字段的属性.它也适用于重构,如果您重命名a",Visual Studio 会捕捉到这一点.
Now you can dig up an attribute on any field by something which is in large checked by the compiler. It also works with refactoring, if you rename 'a' Visual Studio will catch that.
var attr = GetField((MyClass c) => c.a).GetAttribute<DisplayNameAttribute>();
Console.WriteLine(attr.DisplayName);
那里的代码中没有一个文字字符串.
There's not a single literal string in that code there.
这篇关于类成员的自定义属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!