web-dev-qa-db-fra.com

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

J'ai besoin de quelques délégués dans ma classe.

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

Comment?

Ma classe ressemble à ceci:

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
{
   // ?????
}
77
Asaf

Ceux qui déclarent délégué types. Ils n'appartiennent pas à une interface. Les événements tiliser ces types de délégués sont bien pour être dans l'interface si:

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

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

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

127
Jon Skeet

Depuis .NET 3.5, vous pouvez également utiliser les délégués System.Action, ce qui donnerait l'interface suivante:

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

   public event Action Started;
}
27
DELUXEnized

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

Les interfaces ne sont pas là pour vous "rappeler" quoi faire ou quoi inclure dans vos cours. Les interfaces sont des moyens d'abstraction, utilisés dans les méthodes de programmation et de conception orientées objet. Peut-être n’avez-vous pas besoin d’une déclaration d’interface, à moins que vous ne souhaitiez voir des instances de classe concrètes comme interfaces ailleurs dans votre programme (Abstraction).

Si vous souhaitez appliquer certaines normes de codage dans votre projet, essayez 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 (même si je ne vois pas l'intérêt de l'oublier, comme si le délégué n'était pas utilisé, ce n'était pas nécessaire), vous obtiendrez un avertissement/une erreur.

7
Iravanchi

Exposez simplement le délégué en tant que propriété

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

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

L'un de vos commentaires faisait référence au type de gestionnaire d'événement renvoyé. Êtes-vous plus préoccupé par le type de gestionnaire ou par les données renvoyées par l'événement? Si c'est le dernier cas, cela peut aider. Si ce n'est pas le cas, cette solution ne suffira pas, mais peut vous aider à vous rapprocher de ce que vous recherchez.

Tout ce que vous avez à faire est de déclarer vos gestionnaires d'événements en tant que gestionnaires d'événements génériques à la fois dans l'interface et dans votre implémentation. Vous pouvez personnaliser les résultats de retour.

Votre classe commune ressemblerait à ceci:

public class ClsPictures : myInterface
{
    // Implementing the IProcess interface
    public event EventHandler<UpdateStatusEventArgs> UpdateStatusText;
    //no need for this anymore: public delegate void UpdateStatusEventHandler(string Status);

    public event EventHandler<StartedEventArgs> Started;
    //no need for this anymore: public delegate void StartedEventHandler();
}

Votre interface ressemblerait à ceci:

public interface myInterface
{
   event EventHandler<StartedEventArgs> Started;
   event EventHandler<UpdateStatusEventArgs> UpdateStatusText;
}

Maintenant que les arguments d'événement renvoient vos types, vous pouvez les accrocher dans n'importe quel gestionnaire que vous définissez.

Pour référence: https://msdn.Microsoft.com/en-us/library/edzehd2t (v = vs.110) .aspx

1
Reuben Soto

L’interface héritée 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 explicitement et vous aurez toujours besoin de 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);
  }
}
0
Latency