29 votes

Existe-t-il un moyen d'intercepter les setters et les getters en C #?

Dans les deux Ruby et PHP (et je suppose que d'autres langues) il y a quelques méthodes utilitaires qui sont appelé à chaque fois qu'une propriété est définie. ( *instance_variable_set* pour Ruby, *__set* pour PHP).

Alors, disons que j'ai une classe C# comme ceci:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Maintenant, disons que si tout le setter de la propriété de l' Person classe est appelée, je veux appeler une autre méthode tout d'abord, et puis continuer avec le comportement par défaut de l'incubateur, et la même chose s'applique pour les accesseurs de propriété.

Est-ce possible?


Edit: Je veux le faire sans la définition d'un champ de stockage.

25voto

Marc Gravell Points 482669

Généralement pas; quelques options bien;

  • hériter de ContextBoundObject - qui ne permettent cela, mais à un coût de performance
  • écrire une propriété explicite (c'est à dire avec un champ de stockage), et ajouter un utilitaire appel de la méthode manuelle
  • regardez au moment de la compilation des tisserands, comme PostSharp - en général par le repérage d'un attribut ou similaire
  • regardez à l'exécution des générateurs de code, comme proposé par certains DI/outils du Cio (et quelques autres "décorateur" en fonction des outils) - qui soit décorer ou sous-classe de l'objet pour ajouter du code supplémentaire

13voto

Oded Points 271275

Il est possible de le faire directement dans la propriété du corps lui-même, mais alors vous devez utiliser un champ de stockage au lieu de propriétés implémentées automatiquement.

private string firstName;

public string FirstName 
{ 
  get { return firstName;} 
  set 
  {
    if(check(value))
    {
       firstName = value;
    }
  } 
}

Même avec des propriétés implémentées automatiquement, vous obtenez une sauvegarde de champ, ce qui est généré par le compilateur et vous n'avez pas d'accès direct.


Edit:

Voyant que vous ne voulez pas un champ de stockage, vous avez d'autres options à l'aide d'un AOP tels que l'outil de PostSharp pourrait vous aider.

4voto

Mr47 Points 2091

Vous devrez écrire les propriétés en entier pour y parvenir.

2voto

jlafay Points 4670

Je sais que cela a été correctement répondu, mais je vais inclure un exemple pour vous montrer la syntaxe pour atteindre ce que vous voulez:

 public class Person
{
    private 
    public string FirstName
    {
        get
        {
            return _firstName;
        }
        set
        {
            // see how we can call a method below? or any code for that matter..
            _firstName = SanitizeName(value);
        }
    }
}
 

2voto

Richard Everett Points 18318

Êtes-vous en mesure de réécrire votre classe pour implémenter une interface? Si c'est le cas, l'intercepteur d'interface d'Unity pourrait vous fournir ce dont vous avez besoin. Si une interface n'est pas une option, ce lien documente également le type et les intercepteurs d'instance d'Unity.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X