问题描述
我使用的是自定义属性来定义一个类的成员如何映射到属性作为发布表单POST(支付网关)。我有自定义属性的工作蛮好的,我能得到的名的属性,但希望由会员自行获取属性。
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");
VS
getFieldName(obj.Name);
该计划是写一个方法与成员的类序列化到过帐字符串。
The plan is to write a method to serialize the class with members into a postable string.
下面是测试code我在这一点上,其中,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(EHM,前pression树)。
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前pression它可以让编译器生成的前pression树(编译器的类型检查)的虚拟方法。然后你挖成树来获得成员。像这样:
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);
有不是在code有一个单一的文本字符串。
There's not a single literal string in that code there.
这篇关于自定义属性的类成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!