2010-03-26 5 views
5

J'ai une application qui doit déterminer si un utilisateur a apporté une modification à un objet. Ainsi, lorsque l'objet est chargé pour la première fois, je crée une copie en profondeur (en utilisant la sérialisation/désérialisation) et enregistre la copie dans un champ séparé. La copie devient myCurrentObject et l'original devient myOriginalObject.Test d'objets pour les modifications

Maintenant, je dois tester myCurrentObject pour les modifications, ce que je prévois de faire en le comparant à myOriginalObject. Tout ce dont j'ai besoin est un résultat boolean indiquant si des modifications ont été apportées. J'ai déjà déterminé qu'une simple comparaison de hash ne fonctionnera pas. GetHashCode() génère des résultats différents pour les deux objets, même s'il n'y a aucun changement. Je me prépare à écrire une méthode pour faire une comparaison de propriété par propriété, mais avant cela, j'ai pensé que je verrais s'il y a une façon plus simple et plus réutilisable de tester myCurrentObject pour voir si elle a changé de myOriginalObject.

Des suggestions? Merci de votre aide. Que se passe-t-il si un événement est déclenché lors de la modification d'une propriété?

Répondre

5

pourrait vous mettre en œuvre lieu un événement OnPropertyChanged sur chacun de vos biens alors vous pouvez voir si l'événement n'a jamais été levée. Si vous implémentez spécifiquement INotifyPropertyChanged, vous obtiendrez l'avantage supplémentaire que vous pouvez faire en liant WPF si vous le souhaitez.

Si cela n'est pas possible, vous pourriez probablement implémenter une solution avec une réflexion qui traverserait les deux objets à la recherche de différences.

+0

qui va certainement le faire. +1 de moi. –

1

Vous pouvez ajouter un drapeau sale indiquant que tout champ a changé. Définissez le drapeau sale dans le jeu de propriétés.

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

que je fais habituellement ce genre de test comme ceci:

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

puis test:

if(sodomizar(object1)==sodomizar(object2)) 
{ 
doStuff(); 
} 
2
  1. Vous pouvez remplacer la méthode GetHashCode pour refléter vos besoins.
  2. Le code de hachage peut seulement vous dire qu'un objet a définitivement changé, il ne peut pas vous dire qu'un objet n'a pas changé de manière définitive (parce que différents objets peuvent renvoyer le même code de hachage).
  3. Faites étudier la méthode Object.Equals
+0

Utile-- c'est un +1 de moi. –

0

j'envisager d'utiliser une superclasse abstraite contenant deux choses:

  • un drapeau qui déclare que « piste changements » est ou non (par défaut à faux
  • une instance de dictionnaire qui contient l'historique des valeurs clés

... alors appelez Base.TrackChange (string, object) dans chaque accesseur de propriété sur lequel vous êtes intéressé par le changement.Lorsque la chaîne passée est le nom de la propriété (réflexion d'utilisation/tirer le nom de la propriété de la trace de la pile: - signifie que le code dans chaque méthode peut être exactement le même) ... et l'objet passé est simplement la valeur variable meta » '. Une réflexion minutieuse/pile vérification de trace peut signifier que vous pouvez supprimer le paramètre de chaîne sur cette méthode ... vous permet de conserver une entité de classe C# les exigences de codage à un minimum.

Le drapeau est là parce que l'initialisation de l'état de base de l'objet signifie que les changements de propriété (appels accesseurs set) peuvent être jusqu'à ce que l'objet soit complètement hydratée la première fois.

Le dictionnaire est là pour permettre la pêche au chalut des changements (audit?) Et ainsi de suite. Redimensionnez ceci à un second bool si tout ce dont vous avez besoin est simple vrai/faux sur la question 'IsDirty'.

Quelque chose comme:

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