2011-11-30 22 views
11

decir que tengo una clase con cualquier número de propiedades de cualquier tipoAdición de atributos adicionales para cada propiedad de una clase

public class Test 
{ 
public string A {get;set;} 
public object B {get;set;} 
public int C {get;set;} 
public CustomClass D {get;set;} 
} 

Quiero que todos los objetos dentro de esta clase para tener una noción de 'errores' y 'advertencias'. Por ejemplo, en función de alguna condición en otra clase, me gustaría establecer una advertencia en la propiedad A y luego mostrar esa información en la GUI. La GUI no es mi preocupación; más bien, ¿cómo debo configurar esta advertencia? Me gustaría ser capaz de hacer algo como:

Para cada propiedad en una clase, agregue una 'Advertencia' y la propiedad 'error' de tal manera que puedo hacer ..

Test t = new Test(); 
t.A.Warning = "This is a warning that the GUI will know to display in yellow". 
t.B.Error = null; 

¿Cuál es el mejor ¿Cómo hacer esto? Sería bueno si pudiera agregar un atributo personalizado a cada propiedad de la clase que agregaría estas propiedades adicionales y me permitiría acceder a ellas de una manera clara.

He visto soluciones que agregan un diccionario a la clase padre (Test), y luego paso cadenas que coinciden con los nombres de las propiedades, o uso reflection para obtener el nombre de la propiedad y pasarlo, pero preferiría algo más limpio .

Respuesta

8

Se podría añadir un atributo personalizado que desea que la propiedad y luego utilizar un método de extensión en el objeto para acceder a esos atributos.

Algo como esto debería funcionar

primer lugar se necesita para crear su clase de atributo

[AttributeUsage(AttributeTargets.All/*, AllowMultiple = true*/)] 
public class WarningAttribute : System.attribute 
{ 
    public readonly string Warning; 

    public WarningAttribute(string warning) 
    { 
     this.Warning = warning; 
    }  
} 

Más Lectura Here

utilizarlo como tales

[WarningAttribute("Warning String")] 
public string A {get;set;} 

luego acceder a ella como es MSDN Article

public static string Warning(this Object object) 
{ 
    System.Attribute[] attrs = System.Attribute.GetCustomAttributes(object); 

    foreach (System.Attribute attr in attrs) 
     { 
      if (attr is WarningAttrbiute) 
      { 
       return (WarningAttribute)attr.Warning; 
      } 
     } 
} 

Entonces, si usted tiene un artículo que desea tener acceso a la advertencia de la que sólo se puede llamar

test.A.Warning; 

Si tienes intención de establecer la cadena de advertencia le podría aplicar algún tipo de colocador de eso un poco más limpiamente Potencialmente a través de la configuración de un objeto secundario o tipo de propiedad.


Un método alternativo para hacer esto sería en lugar de usar string y object Se puede crear un tipo personalizado genérica para manejar ese valor de la propiedad.

Algo así como

public class ValidationType<T> 
{ 
    public T Value {get; set;} 
    public string Warning {get; set;} 
    public string Error {get; set;} 

    public ValidationType(T value) 
    { 
     Value = value; 
    } 
} 

uso como

var newWarning = new ValidationType<string>("Test Type"); 
newWarning.Warning = "Test STring"; 
Console.WriteLine("newWarning.Value"); 

+0

Gracias por su respuesta. Creo que implementaré esto. No me gusta tener que usar newWarning.Value para acceder realmente a las propiedades de la cadena, pero parece que tendré que sacrificar algo de comodidad en alguna parte. – user981225

1

En primer lugar, los atributos no pueden modificar el objeto en el que se colocaron. A menos que los combines con AOP. Sugeriría usar una clase contenedora alrededor de la clase al heredarla, siempre que las clases no estén selladas. Si están sellados, entonces tendrá que escribir una clase contenedora real, pasando todas las operaciones, excepto las que esté agregando, a un campo privado que sea una instancia de la clase de su envoltura.

Edit: Para facilidad de uso, el método de extensión que se sugirió es probablemente la mejor solución.

2

Si pudieras salirte con la suya con un método en lugar de una propiedad, entonces podrías crear una extensión para el objeto, pero luego sería difícil limitar su uso solo para algunas clases.

Algo así como:

public static void Warning(this object target, string message) 
{ 
... 
} 

public static String GetWarning(this object target) 
{ 
} 

Por supuesto que sería difícil mantener una advertencia de este tipo en el estado del objeto, pero entonces se podría utilizar algunos diccionarios, etc.

+0

Gracias por su publicación, pero preferiría evitar esta solución. Quiero que la propiedad real sepa si tiene o no un error, no para que el objeto padre tenga que recorrer un diccionario de cadenas (por ejemplo). – user981225

2

lugar de tratar de atribuir las propiedades, sugeriría la adición de una colección de propiedades de error/advertencia a una clase base que su los objetos comerciales heredan de.

De esta manera, puede proporcionar información más detallada, puede eliminarlos cuando se han mostrado al usuario y, si está enviando sus datos a través de "la conexión" (servicios web, servicios wcf), la los errores pueden viajar con sus objetos en lugar de requerir un procesamiento especial para enviar los atributos.

Cuestiones relacionadas