Poignée de changement de propriété d'écouteurs d'événement (beaucoup) plus élégamment (dictionnaire?)
bonjour !
Ici, j'ai un simple exemple de classe avec trois champs de type de classe B, et quelques autres trucs.
Comme vous pouvez le voir im écoute sur chaque enfant modification de l'objet.
Depuis que j'ai pu besoin de beaucoup de propriétés de type de classe B, je me demande si il existe un moyen de réduire le code. La création d'un écouteur + une méthode pour chaque semble que je vais avoir BEAUCOUP de code. Comment pourrais-je résoudre ce problème ... à l'aide d'un dictionnaire ou quelque chose de similaire? J'ai dit que le Cio pourrait résoudre ce problème, mais je ne sais pas par où commencer.
public class A : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int _id;
public int Id
{
get { return _id; }
set
{
if (_id == value)
{
return;
}
_id = value;
OnPropertyChanged("Id");
}
}
public string _name;
public string Name
{
get { return _name; }
set
{
if (_name == value)
{
return;
}
_name = value;
OnPropertyChanged("Name");
}
}
public B _firstB;
public B FirstB
{
get { return _firstB; }
set
{
if (_firstB == value)
{
return;
}
if (_firstB != null)
{
FirstB.PropertyChanged -= firstObjectB_Listener;
}
_firstB = value;
if (_firstB != null)
FirstB.PropertyChanged += new PropertyChangedEventHandler(firstObjectB_Listener);
OnPropertyChanged("FirstB");
}
}
public B _secondB;
public B SecondB
{
get { return _secondB; }
set
{
if (_secondB == value)
{
return;
}
if (_secondB != null)
{
FirstB.PropertyChanged -= secondObjectB_Listener;
}
_secondB = value;
if (_secondB != null)
SecondB.PropertyChanged += new PropertyChangedEventHandler(secondObjectB_Listener);
OnPropertyChanged("FirstB");
}
}
public B _thirdB;
public B ThirdB
{
get { return _thirdB; }
set
{
if (_thirdB == value)
{
return;
}
if (_thirdB != null)
{
ThirdB.PropertyChanged -= thirdObjectB_Listener;
}
_thirdB = value;
if (_thirdB != null)
ThirdB.PropertyChanged += new PropertyChangedEventHandler(thirdObjectB_Listener);
OnPropertyChanged("ThirdB");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
void firstObjectB_Listener(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine("Object A has found a change of " + e.PropertyName + " on first object B");
}
void secondObjectB_Listener(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine("Object A has found a change of " + e.PropertyName + " on second object B");
}
void thirdObjectB_Listener(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine("Object A has found a change of " + e.PropertyName + " on third object B");
}
}
OriginalL'auteur no9 | 2010-03-16
Vous devez vous connecter pour publier un commentaire.
La façon la plus élégante que je connaisse est d'utiliser la Programmation Orientée Aspects (AOP) avec un outil tel que PostSharp. J'ai trouvé INotifyPropertyChanged la mise en œuvre des exemples ici et ici. Ceux-ci vous permettent de décorer vos propriétés avec un attribut et PostSharp met ensuite en place INotifyPropertyChanged pour vous lorsque le code est construit.
Je n'ai pas réellement utilisé. Ils ont un forum de support (sharpcrafters.com/forum) et j'ai remarqué que de 1,5 est marqué comme "l'héritage" de sorte que vous aurez probablement à la mise à niveau pour le faire fonctionner.
OriginalL'auteur Jamie Ide
On dirait que vous êtes la configuration d'une chaîne de dépendances. Aucun de l'AOP ou de l'analyse statique des solutions vont gérer cela correctement. Découvrez la mise à Jour des Contrôles, qui utilise le suivi des dépendances à découvrez les chaînes de la dépendance au moment de l'exécution.
Voici ce que votre exemple devient:
OriginalL'auteur Michael L Perry
Une belle façon de simplifier la configuration de vos propriétés peuvent être trouvés ici.
En ce qui concerne votre cascade notifications: je suppose que vous pouvez utiliser l'approche décrite ci-dessus pour gérer la (non-)abonnement d'événements pour les propriétés de mise en œuvre de
INotifyPropertyChanged
.OriginalL'auteur Benjamin Podszun
De simplifier au peu que vous pouvez faire les deux choses.
Tout d'abord, dans le gestionnaire de la PropertyChanged le premier paramètre, l'expéditeur est l'objet qui a déclenché l'événement, au moins si vous avez mises en œuvre le OnPropertyChanged dans la catégorie B de la même manière que dans la classe A. Cela signifie que vous avez seulement besoin d'un traiteur pour tous les B propriétés.
Si vous avez besoin de le faire savoir exactement quels B propriétés ne l'envoi que vous pourriez faire des vérifications dans le BValueListener méthode.
Ayant le même port d'écoute pour tous les B propriétés, nous pouvons alors passer à l'écriture de la propriété setter comme:
Si vous avez vraiment besoin des gestionnaires différents pour chaque propriété que vous pouvez modifier le code ci-dessus pour quelque chose comme
où vous pouvez l'envoyer à l'auditeur de la méthode que vous souhaitez utiliser dans chaque cas.
OriginalL'auteur Robert Höglund
Un outil que vous pourriez envisager est de la T4 (T4 est livré avec VS2010 donc pas de dépendances supplémentaires nécessaires).
T4 est un outil de génération de code qui peut aider à réduire l'entretien de "fastidieux" du code. Pensez ASP/PHP pour le code. C'est également similaire à XML/XSLT.
Pour une excellente introduction à T4 veuillez voir Oleg Sychs blog.
Les avantages de la génération de code dans un cas comme cela, c'est que même si le code généré est superflu le code que vous avez à maintenir (le modèle T4) n'est pas ou, du moins, est moins redondants.
De penser à propos de l'exemple que vous avez fourni, j'ai écrit ce modèle T4:
(Si vous souhaitez essayer ce modèle dans Visual Studio, cliquez sur Ajouter un Nouvel Élément, a choisi le modèle de classe, mais remplacez l'extension .cs .tt, coller la source suivante dans le .tt fichier et de l'enregistrer. Après enregistrez le résultat dans la case correspondante .cs fichier)
Enfin ce qui produit ce résultat:
OriginalL'auteur Just another metaprogrammer