28 votes

Conception de langage C #: implémentation d'interface explicite d'un événement

Petite question sur le langage C# design :))

Si j'avais une interface comme ceci:

interface IFoo {
  int Value { get; set; }
}

Il est possible d'implémenter explicitement cette interface à l'aide de C# 3.0 propriétés implémentées automatiquement:

sealed class Foo : IFoo {
  int IFoo.Value { get; set; }
}

Mais si j'ai eu un événement dans l'interface:

interface IFoo {
  event EventHandler Event;
}

Et en essayant de les implémenter explicitement à l'aide de champ-comme l'événement:

sealed class Foo : IFoo {
  event EventHandler IFoo.Event;
}

Je reçois l'erreur de compilation suivant:

error CS0071: An explicit interface implementation of an event must use event accessor syntax

Je pense que le terrain, comme les événements est une sorte de dualisme pour les propriétés implémentées automatiquement.

Donc ma question est: quelle est la conception de la raison de cette restriction fait?

24voto

Eric Lippert Points 300275

Question interessante. J'ai fouillé dans les archives des notes de langue et j'ai découvert que cette décision a été prise le 13 octobre 1999, mais les notes ne justifient pas la décision.

Du haut de ma tête, je ne vois aucune raison théorique ou pratique pour laquelle nous ne pourrions pas avoir des événements explicitement implémentés sur le terrain. Je ne vois pas non plus pourquoi nous en avons particulièrement besoin. Cela peut devoir rester l'un des mystères de l'inconnu.

22voto

Andreas Huber Points 2936

Je suppose qu'il pourrait avoir à faire avec le fait que vous ne pouvez pas appeler une interface explicite la mise en œuvre des autres membres de la classe:

public interface I
{
    void DoIt();
}

public class C : I
{
    public C()
    {
        DoIt(); // error CS0103: The name 'DoIt' does not exist in the current context
    }

    void I.DoIt() { }
}

Notez que vous pouvez appeler la méthode par upcasting à l'interface de la première:((I)this).DoIt();. Un peu moche, mais ça marche.

Si des événements pourrait être explicitement mis en œuvre comme ControlFlow (l'OP) a suggéré, alors, comment les élever? Considérer:

public interface I
{
    event EventHandler SomethingHappened;
}

public class C : I
{
    public void OnSomethingHappened()
    {
        // Same problem as above
        SomethingHappened(this, EventArgs.Empty);
    }

    event EventHandler I.SomethingHappened;
}

Ici, vous ne pouvez même pas soulever de l'événement par l'upcasting de l'interface tout d'abord, parce que les événements ne peuvent être soulevées à partir de l'intérieur de la mise en œuvre de la classe. Il semble donc judicieux d'exiger de l'accesseur de la syntaxe explicitement mis en œuvre des événements.

12voto

Stécy Points 2997

Lorsqu'il est explicitement mise en œuvre d'un événement qui s'est déclaré dans une interface, vous devez utiliser manuellement fournir les ajouter et supprimer des événements accesseurs qui sont généralement fournis par le compilateur. L'accesseur code peut se connecter à l'interface d'événement à un autre événement dans votre classe ou pour son propre type de délégué.

Par exemple, cela va déclencher d'erreur CS0071:

public delegate void MyEvent(object sender);

interface ITest
{
    event MyEvent Clicked;
}

class Test : Itest
{
    event MyEvent ITest.Clicked;  // CS0071
    public static void Main() { }
}

La manière correcte serait:

public delegate void MyEvent(object sender);

interface ITest
{
    event MyEvent Clicked;
}

class Test : Itest
{
    private MyEvent clicked;

    event MyEvent Itest.Clicked
    {
        add
        {
            clicked += value;
        }

        remove
        {
            clicked -= value;
        }
    }

    public static void Main() { }
}

voir l' Erreur du Compilateur CS0071

1voto

EtherealMonkey Points 116

Ce ne serait pas en fait une pensée originale par moi-même.

Cependant, j'ai pensé que je pourrais répondre à ceci:

"Du haut de ma tête, je ne vois pas théorique ou pratique, pourquoi on ne pourrait pas avoir de champ comme explicitement mis en œuvre des événements. Je ne vois aucune raison pour laquelle nous avons particulièrement besoin. Cela peut avoir à rester l'un des mystères de l'inconnu." -Eric Lippert


Dans le Chapitre 23 de Un Programmeur d'Introduction à C#, Deuxième Édition, Eric Gunnerson a écrit:

"[I]f une autre classe voulais aussi appelée lorsque le bouton a été cliqué, l'opérateur += pourraient être utilisés, comme ceci:

bouton.Click += new Bouton.ClickHandler(OtherMethodToCall);

Malheureusement, si l'autre classe n'était pas prudent, il peut faire ce qui suit:

bouton.Cliquez sur = new Bouton.ClickHandler(OtherMethodToCall);

Ce serait une mauvaise chose, car cela voudrait dire que notre ButtonHandler serait décrochée et seule la nouvelle méthode doit être appelée."

...

"Ce qui est nécessaire est une façon de protéger le délégué champ de sorte qu'il est accessible uniquement à l'aide de += et -=."


Il se passe au cours de la prochaine quelques pages à commenter, y compris les ajouter() et remove() les méthodes à implémenter ce comportement; être capable d'écrire à ceux des méthodes directement, et la conséquence de l'allocation de stockage pour inutiles délégué références.

Je voudrais ajouter plus, mais je respecte l'auteur de trop de le faire sans son autorisation. Je recommande de trouver un exemplaire de ce livre et de recommander quoi que ce soit par Eric Gunnerson en général (blog, etc...)

De toute façon, j'espère que c'est pertinent pour le sujet et, si oui, j'espère qu'elle brille la lumière sur ce "mystère de l'inconnu"? (J'ai lu ça très au chapitre et à la recherche d'un Débordement de Pile pour un aperçu de gestionnaire d'événement logique de considérations lors de la création des collections personnalisées à partir d'objets personnalisés) - je ne mentionne cela parce que je revendique aucune autorité sur ce sujet particulier. Je suis simplement un étudiant à la recherche de "l'illumination" moi :-)

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