propiedades - readonly c#
¿Cómo acceder al atributo Descripción en una propiedad o en const en C#? (4)
¿Cómo se accede a la propiedad Descripción en un const o una propiedad, es decir,
public static class Group
{
[Description( "Specified parent-child relationship already exists." )]
public const int ParentChildRelationshipExists = 1;
[Description( "User is already a member of the group." )]
public const int UserExistsInGroup = 2;
}
o
public static class Group
{
[Description( "Specified parent-child relationship already exists." )]
public static int ParentChildRelationshipExists {
get { return 1; }
}
[Description( "User is already a member of the group." )]
public static int UserExistsInGroup {
get { return 2; }
}
}
En la clase de llamada, me gustaría acceder a la propiedad Descripción, es decir,
int x = Group.UserExistsInGroup;
string description = Group.UserExistsInGroup.GetDescription(); // or similar
También estoy abierto a ideas sobre otras metodologías.
EDITAR: Debería haber mencionado que he visto un ejemplo proporcionado aquí: ¿las propiedades implementadas automáticamente admiten atributos?
Sin embargo, estoy buscando un método para acceder al atributo de descripción sin tener que ingresar un literal de cadena en el tipo de propiedad, es decir, prefiero no hacer esto:
typeof(Group).GetProperty("UserExistsInGroup");
Algo similar a un Método de Extensión; similar al siguiente método que devolverá el atributo Descripción en un Enum a través de un Método de extensión:
public static String GetEnumDescription( this Enum obj )
{
try
{
System.Reflection.FieldInfo fieldInfo =
obj.GetType().GetField( obj.ToString() );
object[] attribArray = fieldInfo.GetCustomAttributes( false );
if (attribArray.Length > 0)
{
var attrib = attribArray[0] as DescriptionAttribute;
if( attrib != null )
return attrib.Description;
}
return obj.ToString();
}
catch( NullReferenceException ex )
{
return "Unknown";
}
}
Aquí hay una clase de ayuda que estoy usando para procesar atributos personalizados en .NET
public class AttributeList : List<Attribute>
{
/// <summary>
/// Gets a list of custom attributes
/// </summary>
/// <param name="propertyInfo"></param>
/// <returns></returns>
public static AttributeList GetCustomAttributeList(ICustomAttributeProvider propertyInfo)
{
var result = new AttributeList();
result.AddRange(propertyInfo.GetCustomAttributes(false).Cast<Attribute>());
return result;
}
/// <summary>
/// Finds attribute in collection by its type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T FindAttribute<T>() where T : Attribute
{
return (T)Find(x => typeof(T).IsAssignableFrom(x.GetType()));
}
public bool IsAttributeSet<T>() where T : Attribute
{
return FindAttribute<T>() != null;
}
}
También pruebas unitarias para MsTest que muestran cómo usar esta clase
[TestClass]
public class AttributeListTest
{
private class TestAttrAttribute : Attribute
{
}
[TestAttr]
private class TestClass
{
}
[TestMethod]
public void Test()
{
var attributeList = AttributeList.GetCustomAttributeList(typeof (TestClass));
Assert.IsTrue(attributeList.IsAttributeSet<TestAttrAttribute>());
Assert.IsFalse(attributeList.IsAttributeSet<TestClassAttribute>());
Assert.IsInstanceOfType(attributeList.FindAttribute<TestAttrAttribute>(), typeof(TestAttrAttribute));
}
}
http://www.kozlenko.info/2010/02/02/getting-a-list-of-custom-attributes-in-net/
De acuerdo, he visto tu edición, no estoy seguro de que puedas hacerlo con los métodos de extensión, ya que serían conscientes del tipo de la clase que los contiene.
Esto va a sonar un poco loco, pero ¿qué tal si creamos una clase nueva como "DescribedInt", que tendría un operador de conversión implícito que le permitiera usarlo como int automáticamente? Podrás usar más o menos cómo describes. Aún tendrá una descripción, pero cuando necesite usarla como Int, no necesitará obtener la propiedad .Data ...
p.ej:
private void ExampleUse()
{
int myvalue = Group.A; //see, no need to cast or say ".Data" - implicit cast
string text = Group.A.Description;
// hacer cosas con valores ...}
public static class Group
{
public static DescribedInt A = new DescribedInt(12, "some description");
public static DescribedInt B = new DescribedInt(88, "another description");
}
public class DescribedInt
{
public readonly int data;
public readonly string Description;
public DescribedInt(int data, string description)
{
this.data = data;
this.Description = description;
}
//automatic cast to int
public static implicit operator int(DescribedInt orig)
{
return orig.data;
}
//public DescribedInt(string description)
//{
// this.description = description;
//}
//if you ever need to go the "other way"
//public static implicit operator DescribedInt(int orig)
//{
// return new DescribedInt(orig, "");
//}
}
Pruebe lo siguiente
var property = typeof(Group).GetProperty("UserExistsInGroup");
var attribute = property.GetCustomAttributes(typeof(DescriptionAttribute), true)[0];
var description = (DescriptionAttribute)attribute;
var text = description.Description;
Puede llamar a MemberInfo.GetCustomAttributes () para obtener los atributos personalizados definidos en un miembro de un Type
. Puede obtener MemberInfo
para la propiedad haciendo algo como esto:
PropertyInfo prop = typeof(Group).GetProperty("UserExistsInGroup",
BindingFlags.Public | BindingFlags.Static);