98 votes

Comment ajouter un délégué à une interface C#

J'ai besoin d'avoir des délégués dans ma classe.

J'aimerais utiliser l'interface pour me "rappeler" de définir ces délégués.

Comment ?

Ma classe ressemble à ça :

public class ClsPictures : myInterface
{
    // Implementing the IProcess interface
    public event UpdateStatusEventHandler UpdateStatusText;
    public delegate void UpdateStatusEventHandler(string Status);

    public event StartedEventHandler Started;
    public delegate void StartedEventHandler();
}

J'ai besoin d'une interface pour forcer ces délégués :

public interface myInterface
{
   // ?????
}

149voto

Jon Skeet Points 692016

Il s'agit de déclarer un délégué types . Ils n'ont pas leur place dans une interface. Les événements en utilisant Ces types de délégués peuvent être intégrés à l'interface :

public delegate void UpdateStatusEventHandler(string status);
public delegate void StartedEventHandler();

public interface IMyInterface
{       
    event UpdateStatusEventHandler StatusUpdated;    
    event StartedEventHandler Started;
}

L'implémentation ne va pas (et ne devrait pas) redéclarer le type de délégué, pas plus qu'elle ne redéclarerait tout autre type utilisé dans une interface.

0 votes

Ça ne marche pas pour moi. Je suis certain d'avoir tout fait de cette manière, et pourtant, mon gestionnaire au sein de mon interface n'est pas reconnu. Ma classe qui implémente l'interface se plaint que la classe ne correspond pas au type de retour de l'interface de System.EventHandler.

1 votes

@Chucky : Il semble que vous devriez poser une nouvelle question avec un exemple court mais complet démontrant le problème. La réponse que j'ai donnée est vraiment hace travail.

6 votes

Je n'avais pas réalisé que les délégués avaient le même niveau d'accessibilité que les classes. J'ai toujours pensé qu'ils devaient être encapsulés dans une classe.

34voto

DELUXEnized Points 363

Depuis .NET 3.5, vous pouvez également utiliser les délégués System.Action, sans avoir à déclarer votre propre type.

Cela donnerait l'interface suivante :

public interface myInterface
{       
   // Implementing the IProcess interface
   event Action<String> UpdateStatusText;

   event Action Started;
}

1 votes

+1. Je trouve que les types Action/Func sont beaucoup plus élégants (et lisibles) que les types délégués traditionnels. y vous pouvez les définir dans votre interface.

3 votes

Cette réponse ne répond pas à la question (comment implémenter myInterface).

12voto

Cornet Gregory Points 121

Il suffit d'exposer le délégué comme une propriété

public delegate void UpdateStatusEventHandler(string status);
public delegate void StartedEventHandler();

public interface IMyInterface
{       
    UpdateStatusEventHandler StatusUpdated {get; set;}    
    StartedEventHandler Started {get; set;}
}

7voto

Iravanchi Points 1264

La réponse de Jon Skeet est juste, je veux juste ajouter une note.

Les interfaces ne sont pas là pour vous "rappeler" ce que vous devez faire, ou ce que vous devez inclure dans vos classes. Les interfaces sont des moyens d'abstraction, utilisés dans la programmation orientée objet et les méthodes de conception. Peut-être n'avez-vous pas du tout besoin d'une déclaration d'interface, à moins que vous ne vouliez voir certaines instances de classes concrètes comme l'interface ailleurs dans votre programme (abstraction).

Si vous souhaitez appliquer certaines normes de codage dans votre projet, vous pouvez essayer d'utiliser des outils d'analyse de code (comme dans Visual Studio) - Ils permettent des extensions, que vous pouvez incorporer pour ajouter vos propres règles d'analyse de code.

En utilisant l'analyse de code, si vous "oubliez" d'ajouter les délégués (bien que je ne vois pas l'intérêt de l'oublier, car si le délégué n'est pas utilisé, il n'est pas nécessaire), vous obtiendrez un avertissement / une erreur.

2 votes

Vous avez peut-être raison, mais il y a des fois où vous faites des suppositions que même avec une bonne documentation, il est difficile de se rappeler après un certain temps. J'essaie de réutiliser mon code mais parfois je ne peux pas me rappeler ce qui est le noyau et ce qui ne l'est pas (quand il s'agit de délégués - il m'est difficile de voir la situation dans son ensemble...).

1voto

Latency Points 16

L'interface héritée au sein de votre classe dérivée vous rappellera de définir et de lier les éléments que vous avez déclarés dans celle-ci.

Mais vous pouvez aussi vouloir l'utiliser de manière explicite et vous devrez alors l'associer à un objet.

Par exemple, en utilisant un modèle d'inversion de contrôle :

class Form1 : Form, IForm {
   public Form1() {
     Controls.Add(new Foo(this));
   }

   // Required to be defined here.
   void IForm.Button_OnClick(object sender, EventArgs e) {
     ...
     // Cast qualifier expression to 'IForm' assuming you added a property for StatusBar.
     //((IForm) this).StatusBar.Text = $"Button clicked: ({e.RowIndex}, {e.SubItem}, {e.Model})";
   }
 }

Vous pouvez essayer quelque chose comme ça.

interface IForm {
  void Button_OnClick(object sender, EventArgs e);
}

class Foo : UserControl {
  private Button btn = new Button();

  public Foo(IForm ctx) {
     btn.Name = "MyButton";
     btn.ButtonClick += ctx.Button_OnClick;
     Controls.Add(btn);
  }
}

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