Question

J'ai une classe avec un tas de propriétés qui ressemblent à ceci:

public string Name
{
    get { return _name; }
    set { IsDirty = true; _name = value; }
}

Ce serait beaucoup plus facile si je pouvais compter sur C # 3.0 pour générer le magasin de support pour ceux-ci, mais existe-t-il un moyen de factoriser IsDirty = true; afin que je puisse écrire mes propriétés quelque chose comme ça et toujours avoir le même comportement:

[MakesDirty]
public string Name { get; set; }
Était-ce utile?

La solution

Non. Non sans écrire beaucoup plus de code (mystérieux?) Que la version d'origine (vous devez utiliser la réflexion pour rechercher l'attribut dans la propriété et ce qui ne l'est pas. C’est le genre de duplication avec lequel je peux vivre.

MS a le même besoin de de déclencher des événements lorsqu'une propriété est modifiée . INotifyPropertyChanged est une interface vitale pour les notifications de modification. Chaque implémentation que j'ai vue jusqu'à présent fait

set
{ 
  _name = value; 
  NotifyPropertyChanged("Name"); 
}

Si cela était possible, je penserais que ces types intelligents de MS auront déjà quelque chose comme ça en place.

Autres conseils

Vous pouvez essayer de configurer un extrait de code pour faciliter la création de ceux-ci.

Si vous voulez vraiment utiliser cette méthode, modifier le code en utilisant un attribut, il existe plusieurs façons de le faire et elles sont toutes liées à la programmation orientée aspect (AOP). Découvrez PostSharp , un post-compilateur permettant de modifier votre code lors d'une étape de compilation. Par exemple, vous pouvez définir un attribut personnalisé pour vos propriétés (ou aspect, comment il est appelé dans AOP), qui injecte du code dans des paramètres de propriété, qui marque vos objets comme étant corrompus. Si vous souhaitez des exemples de cette opération, vous pouvez consulter leurs didacticiels .

Mais soyez prudent avec AOP car vous pouvez tout aussi facilement créer plus de problèmes que vous essayez de résoudre si vous ne l'utilisez pas correctement.

Il existe plus de frameworks AOP, certains utilisant la post-compilation et d'autres utilisant des mécanismes d'interception de méthodes présents dans .Net, ces derniers présentant certains inconvénients en termes de performances par rapport au premier.

Non, lorsque vous utilisez des propriétés automatiques, vous n'avez aucun contrôle sur la mise en œuvre. La meilleure option consiste à utiliser un outil de création de modèles, des extraits de code ou de créer une SetValue privée <T & Gt; (référence T backingField, valeur T) qui encapsule la logique de définition.

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);
   }
}

L’autre alternative pourrait être un générateur de code tel que Codemith pour automatiser la création des propriétés. Cela serait particulièrement utile si les propriétés que vous créez sont des colonnes dans une table de base de données

Je peux recommander l'utilisation de Bibliothèque d'entreprise à cette fin. Policy Application Block fournit l'infrastructure pour faire & "Quelque chose &"; (quelque chose = vous pouvez le coder vous-même) chaque fois que vous entrez / quittez une méthode par exemple. Vous pouvez contrôler le comportement avec des attributs. Considérez cela comme un indice et allez dans les détails avec la documentation de la bibliothèque d'entreprise.

Un attribut DefaultValueAttribute peut être attribué à une propriété. Il est principalement utilisé par les outils du concepteur afin qu'ils puissent indiquer quand une propriété a été modifiée, mais il peut s'agir d'un & "ranger &"; manière de décrire la valeur par défaut d’une propriété et d’identifier ses modifications.

Vous devez utiliser Reflection pour identifier les modifications de propriétés - ce qui n’est pas réellement aussi coûteux si vous n’en faites pas beaucoup!

Mise en garde: vous ne pourrez pas savoir si une propriété qui a été modifiée est passée d'une valeur autre que par défaut à celle par défaut.

Je dirais que le meilleur moyen de résoudre ce problème consiste à utiliser la programmation orientée aspect (AOP). Mats Helander a écrit sur ce sujet dans InfoQ . L'article est un peu brouillon, mais il est possible de suivre. Il existe un certain nombre de produits différents qui font AOP dans l'espace .NET, je recommande PostSharp.

Si vous utilisez les attributs, je suis presque certain que vous devrez lancer votre propre logique pour en déduire ce qu’ils veulent dire et ce qu’il faut faire à leur sujet. Tout ce qui utilise vos objets de classe personnalisés devra avoir un moyen d’effectuer ces actions / vérifications d’attributs, de préférence à l’instanciation.

Sinon, vous envisagez d'utiliser peut-être des événements. Vous devez toujours ajouter l'événement à chaque méthode de jeu, mais l'avantage serait de ne pas coder en dur la procédure à suivre pour les jeux modifiés sur chaque propriété et de contrôler, à un endroit donné, ce qui doit être fait. Cela introduirait à tout le moins un peu plus de réutilisation de code.

Objet ContextBound. Si vous créez une classe qui étend un objet lié au contexte et que vous créez un attribut ContextAttribute, vous pouvez intercepter les appels passés à une telle propriété et définir IsDirty. .NET créera un proxy pour votre classe afin que tous les appels passent par quelque chose qui ressemble à un puits d’accès distant.

Le problème avec une telle approche est que votre proxy ne sera appelé que s’il est appelé en externe. Je vais vous donner un exemple.

class A
{
    [Foo]
    public int Property1{get; set;}
    public int Property2{get {return variable;} set{ Property1 = value; variable = value; }
}

Lorsque property1 est appelé depuis une autre classe, votre proxy sera appelé. Mais si une autre classe appelle property2, même si l'ensemble de property2 appellera property1, aucun proxy ne sera appelé (un proxy n'est pas nécessaire si vous êtes dans la classe elle-même).

Il existe de nombreux exemples de code d'utilisation de ContextBoundObjects. Examinez-le.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top