property net example custom attribute asp c# reflection attributes custom-attributes

net - reflection c# example



Atributos personalizados en miembros de la clase (2)

Puedes hacer la mitad un poco más simple:

foreach (PropertyMapping attrib in Attribute.GetCustomAttributes(i, typeof(PropertyMapping))) { ret += map.FieldName; // whatever you want this to do... }

por cierto; debe hacer un hábito de terminar atributos con la palabra Attribute . Incluso si esto causa la duplicación (ver [XmlAttributeAttribute] ).

Sin embargo, re serialización; eso no siempre es trivial. Una cantidad engañosa de código entra en marcos de serialización como Json.NET, etc. El enfoque normal podría ser obtener un convertidor de tipo, pero en muchos sentidos esto es más fácil con un PropertyDescriptor :

foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(obj)) { Console.WriteLine("{0}={1}", prop.Name, prop.Converter.ConvertToInvariantString( prop.GetValue(obj))); }

Estoy utilizando un atributo personalizado para definir cómo se asignan los miembros de una clase a las propiedades para publicar como una publicación de formulario (Payment Gateway). Tengo el atributo personalizado funcionando bien, y puedo obtener el atributo por "nombre", pero me gustaría obtener el atributo por el miembro mismo.

Por ejemplo:

getFieldName("name");

vs

getFieldName(obj.Name);

El plan es escribir un método para serializar la clase con miembros en una cadena postable.

Este es el código de prueba que tengo en este punto, donde ret es una cadena y PropertyMapping es el atributo personalizado:

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; } } }

¡Gracias por adelantado!


Realmente no puedes hacer esto, a menos que uses C # 3.0, en cuyo caso necesitarás confiar en LINQ (ehm, árboles de expresiones).

Lo que debes hacer es crear un método ficticio para una expresión lambda que permita al compilador generar el árbol de expresiones (el compilador realiza la comprobación de tipos). Luego cavas en ese árbol para obtener el miembro. Al igual que:

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... }

Dada la siguiente clase:

class MyClass { public int a; }

Puede obtener metadatos como este:

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

Con una referencia a ese campo, puede desenterrar cualquier atributo de la manera habitual. es decir, reflexión.

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

Ahora puede desenterrar un atributo en cualquier campo mediante algo que el compilador revisa en gran medida. También funciona con la refactorización. Si cambia el nombre de ''a'', Visual Studio lo detectará.

var attr = GetField((MyClass c) => c.a).GetAttribute<DisplayNameAttribute>(); Console.WriteLine(attr.DisplayName);

No hay una sola cadena literal en ese código allí.