custom attributes c#
c#propiedades con código repetido (10)
Tengo una clase con muchas propiedades que se ven así:
public string Name
{
get { return _name; }
set { IsDirty = true; _name = value; }
}
Sería mucho más fácil si pudiera confiar en C # 3.0 para generar la tienda de respaldo para estos, pero ¿hay alguna forma de factorizar IsDirty = true? para poder escribir mis propiedades de esta manera y obtener el mismo comportamiento:
[MakesDirty]
public string Name { get; set; }
Diría que la mejor manera de resolver esto es usar la Programación Orientada a Aspectos (AOP). Mats Helander escribió sobre esto en InfoQ . El artículo es un poco complicado, pero es posible seguirlo. Hay varios productos diferentes que hacen AOP en el espacio .NET, recomiendo PostSharp.
No, cuando usas propiedades automáticas, no tienes ningún control sobre la implementación. La mejor opción es usar una herramienta de plantillas, fragmentos de código o crear un SetValue <T
> privado (ref T backingField, T value) que encapsula la lógica del setter.
private void SetValue<T>(ref T backingField, T value)
{
if (backingField != value)
{
backingField = value;
IsDirty = true;
}
}
public string Name
{
get
{
return _name;
}
set
{
SetValue(ref _name, value);
}
}
Si realmente quieres ir de esa manera, para modificar lo que hace el código usando un atributo, hay algunas maneras de hacerlo y todos están relacionados con AOP (programación orientada a aspectos). Echa un vistazo a PostSharp , que es un postcompilador que puede modificar tu código en un paso posterior a la compilación. Por ejemplo, puede configurar un atributo personalizado para sus propiedades (o aspecto, cómo se llama en AOP) que inyecta código dentro de los ajustadores de propiedades, que marca los objetos como sucios. Si desea algunos ejemplos de cómo se logra esto, puede consultar sus tutoriales .
Pero ten cuidado con AOP y porque puedes crear fácilmente más problemas al usarlo que estás tratando de resolver si no se usa correctamente.
Hay más frameworks de AOP que usan post compilación y algunos usan mecanismos de interceptación de métodos que están presentes en .Net, los últimos tienen algunos inconvenientes de rendimiento en comparación con el primero.
Si vas con Atributos, estoy bastante seguro de que tendrás que desarrollar tu propia lógica para deducir lo que significan y qué hacer con ellos. Cualquiera que sea el uso de sus objetos de clase personalizados tendrá que tener una forma de realizar estas acciones / verificaciones de atributos, preferiblemente en instanciación.
De lo contrario, estás viendo el uso de tal vez eventos. Todavía tendría que agregar el evento a cada método de conjunto, pero el beneficio sería que no está codificando qué hacer con los conjuntos sucios en cada propiedad y puede controlar, en un lugar, lo que se debe hacer. Eso, como mínimo, introduciría un poco más de reutilización de código.
ContextBound object Si crea una clase que amplía el objeto vinculado al contexto y crea un atributo de contexto, puede interceptar las llamadas realizadas a dicha propiedad y establecer IsDirty. .NET creará un proxy para su clase, de modo que todas las llamadas superen algo así como un receptor remoto.
Sin embargo, el problema con este enfoque es que su proxy solo se invocará cuando se llame externamente. Te daré un ejemplo.
clase A {[Foo] public int Propiedad1 {get; establecer;} public int Property2 {get {return variable;} set {Property1 = value; variable = valor; }
}
Cuando se llama a property1 desde otra clase, se invocará tu proxy. Pero si otra clase llama a property2, aunque el conjunto de property2 llamará a property1 no se invocará ningún proxy (no se necesita un proxy cuando estás en la clase).
Hay un montón de código de muestra de usar contextboundobjects, míralo.
Hay un DefaultValueAttribute que se puede asignar a una propiedad, esto es utilizado principalmente por las herramientas de diseño para que puedan indicar cuándo se ha cambiado una propiedad, pero podría ser una manera "ordenada" de describir cuál es el valor predeterminado para una propiedad , y así poder identificar si ha cambiado.
Debería usar Reflection para identificar cambios en la propiedad, que en realidad no es tan caro a menos que lo haga en gran medida.
Advertencia: No podría saber si una propiedad se ha cambiado ATRÁS de un valor no predeterminado al valor predeterminado.
La otra alternativa podría ser un generador de código como codesmith para automatizar la creación de las propiedades. Esto sería especialmente útil si las propiedades que está creando son columnas en una tabla de base de datos
Podría intentar configurar un fragmento de código para que sea más fácil crearlos.
Puedo recomendar el uso de Enterprise Library para ese propósito. Policy Application Block ofrece la infraestructura para hacer "algo" (algo = usted puede codificar eso por su cuenta) cada vez que ingresa / sale de un método, por ejemplo. Puedes controlar el comportamiento con atributos. Tómelo como una pista y entre en detalles con la documentación de la biblioteca empresarial.
No. No sin escribir mucho más (¿arcano?) Código que la versión original (Tendría que usar el reflejo para verificar el atributo en la propiedad y lo que no ... ¿mencioné que era ''más lento'') ... Esto es el tipo de duplicación con la que puedo vivir
MS tiene la misma necesidad de generar eventos cuando se cambia una propiedad . INotifyPropertyChanged que es una interfaz vital para las notificaciones de cambio. Cada implementación que he visto hace
set
{
_name = value;
NotifyPropertyChanged("Name");
}
Si fuera posible, me imagino que esos tipos inteligentes en MS ya tendrían algo así en su lugar ...