2010-03-26 9 views
5

Tengo una aplicación que necesita determinar si un usuario ha realizado un cambio en un objeto. Entonces, cuando el objeto se carga por primera vez, creo una copia profunda (usando serialización/deserialización) y guardo la copia en un campo separado. La copia se convierte en myCurrentObject, y el original se convierte en myOriginalObject.Prueba de objetos para cambios

Ahora necesito probar myCurrentObject para ver los cambios, lo cual planeo hacer comparándolo con myOriginalObject. Todo lo que necesito es un resultado boolean que indique si se han realizado cambios. Ya he determinado que una simple comparación de hashcode no funcionará. GetHashCode() genera resultados diferentes para los dos objetos, incluso cuando no hay cambios.

Me estoy preparando para escribir un método para hacer una comparación de propiedad por propiedad, pero antes de hacerlo, pensé que verificaría si hay una manera más simple y más reutilizable de probar myCurrentObject para ver si ha cambiado de myOriginalObject.

¿Alguna sugerencia? Gracias por tu ayuda.

Respuesta

5

En vez podrías poner en práctica un evento OnPropertyChanged en cada una de sus propiedades a continuación, usted podría ver si el evento se meten. Si implementa específicamente INotifyPropertyChanged, obtendrá el beneficio adicional de poder hacer el enlace WPF si lo desea.

Si eso no es posible, probablemente podría implementar una solución con reflexión que atravesaría ambos objetos buscando diferencias.

+0

Eso definitivamente lo hará. +1 de mi parte –

1

Puede agregar un indicador sucio que indique que cualquier campo ha cambiado. Establezca la bandera sucia en el conjunto de propiedades.

public bool IsDirty { get { return m_IsDirty; } } 
public string Name { 
    set 
    { 
     m_Name = value; 
     m_IsDirty = true; 
    } 
} 
0

por lo general hago este tipo de prueba como esta:

public string sodomizar(myObject object) 
{ 
    return object.prop1.ToString() + object.prop2.ToString(); 
} 

entonces prueba:

if(sodomizar(object1)==sodomizar(object2)) 
{ 
doStuff(); 
} 
2
  1. Puede reemplazar el método GetHashCode para reflejar sus necesidades.
  2. El código hash solo puede decirle que un objeto ha cambiado definitivamente, no puede decirle que un objeto definitivamente no ha cambiado (porque diferentes objetos pueden devolver el mismo código hash).
  3. investigamos el método Object.Equals
+0

Útil-- es un +1 de mí. –

0

que sería considerar el uso de una superclase abstracta que contiene dos cosas:

  • una bandera que declara si 'pista cambios' está encendido o no (por defecto a falsa)
  • una instancia Diccionario que contiene la historia de valor llave

... luego llame a Base.TrackChange (cadena, objeto) en cada acceso a la propiedad que le interese cambiar.Cuando la cadena que se pasa es el nombre de la propiedad (uso reflexión/tirar del nombre de la propiedad de la traza de la pila: - significa que el código en cada método puede ser exactamente el mismo) ... y el objeto pasado es simplemente el 'valor de la variable meta '. Algunos de reflexión/pila cuidadoso control huella que significa que usted puede quitar el parámetro de cadena de este método ... significa que mantener entidad Clase C# requerimientos a un mínimo de codificación.

La bandera está allí porque inicialización estado básico del objeto significa que los cambios de propiedad (llamadas conjunto de descriptor de acceso) pueden hacerse hasta que el objeto está completamente hidratado primera vez.

El diccionario está ahí para permitir la pesca de arrastre de los cambios (auditoría?) Y así sucesivamente. Escala esto a un segundo bool si todo lo que necesitas es simple verdadero/falso en la pregunta 'IsDirty'.

Algo así como:

public abstract Class EntityBase 
{ 
    private bool _changesAreTracking = false; 
    private Dictionary<string, object> _changes = null; 
    public EntityBase() {} 

    public TrackChange(string propertyName, object value) 
    { 
     if(_changesAreTracking) 
     { 
      if(_changes == null) { _changes = new Dictionary<string, object>(); } 

      _changes.Add(propertyName, value); 
     } 
    } 

    public void StartTrackChanges() 
    { 
     _changesAreTracking = true; 
    } 

    public bool HasChanged() 
    { 
     bool returnThis = false; 

     if(_changes != null && _changes.Keys.Count() > 0) 
     { 
      returnThis = true; 
     } 

     return returnThis; 
    } 

    public bool HasChanged(string propertyName) 
    { 
     bool returnThis = false; 

     if(_changes != null && _changes.Keys.Contains(propertyName)) 
     { 
      returnThis = true; 
     } 

     return returnThis; 
    } 
} 
Cuestiones relacionadas