Soulever des Événements de Classe de Base dans les Classes Dérivées de C#
J'ai une classe de base DockedToolWindow : Forme, et de nombreuses classes qui dérivent de DockedToolWindow. J'ai une classe de conteneur qui contient et attribue les événements DockedToolWindow objets, mais je tiens à appeler les événements de la classe enfant.
En fait, j'ai une question sur la façon de mettre en œuvre ce que ce Site MSDN me dit de faire. Cette section ci-dessous donne moi le problème:
//The event. Note that by using the generic EventHandler<T> event type
//we do not need to declare a separate delegate type.
public event EventHandler<ShapeEventArgs> ShapeChanged;
public abstract void Draw();
//The event-invoking method that derived classes can override.
protected virtual void OnShapeChanged(ShapeEventArgs e)
{
//Make a temporary copy of the event to avoid possibility of
//a race condition if the last subscriber unsubscribes
//immediately after the null check and before the event is raised.
EventHandler<ShapeEventArgs> handler = ShapeChanged;
if (handler != null)
{
handler(this, e);
}
}
Sûr cet exemple compile et fonctionne, mais lorsque je remplace "ShapeChanged" avec "Move" (un événement que j'ai acquis de dérivation à partir de la Forme), c'erreurs en disant: je ne peux pas le Déplacer sur le côté droit sans += ou -=. J'ai également supprimé les ShapeEventArgs générique balises.
Toute inciter sur les raisons de ce qui ne fonctionne pas? Quelle est la différence entre un événement déclaré au sein de la classe et celui qui est hérité?
OriginalL'auteur Game_Overture | 2009-04-23
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas directement le feu événements de classe de base. C'est exactement la raison pour laquelle vous avez eu à faire à votre
OnShapeChanged
méthodeprotected
au lieu deprivate
.Utilisation de la base.OnMove() à la place.
OnMove déclenche l'événement de Déplacement, de la même manière que OnShapeChanged les feux de la ShapeChanged événement dans votre code. C'est un modèle commun pour ajouter des membres protégés qui déclenchent des événements afin de les rendre visibles pour les classes dérivées. Dans ce cas, le préfixe "on" est généralement ajoutée (OnMove, OnClick, etc.)
Pour voir où le cadre fait feux de le Déplacer l'événement, utilisez le Réflecteur de l'outil (red-gate.com/products/reflector) pour obtenir le code source du Formulaire.OnMove méthode.
[Remarque] le Réflecteur a, depuis lors, est devenu une application payante, donc (si vous voulez une application gratuite), vous aurez besoin de vérifier out ILSpy ou une autre application similaire.
JustDecompile à partir de Telerik est gratuit.
OriginalL'auteur Groo
À partir du langage C# spec, l'article 10.7 (italiques ajoutés):
Ainsi, la raison pour laquelle vous ne pouvez pas traiter le mouvement de l'événement comme un champ, c'est qu'il est défini dans un autre type (dans ce cas, votre super-classe). Je suis d'accord avec @womp est la spéculation que les concepteurs ont fait ce choix pour éviter involontaire monkeying avec l'événement. Il semble évidemment mauvais pour permettre sans rapport avec les types (types non dérivé du type de déclarer l'événement) pour ce faire, mais même pour les types dérivés, il pourrait ne pas être souhaitable. Ils auraient probablement dû inclure la syntaxe pour permettre à l'événement de la déclaration doit être faite
private
ouprotected
à l'égard du domaine de style d'utilisation, donc je suppose qu'ils ont choisi de simplement rejeter entièrement.OriginalL'auteur Charlie
La différence est portée. À l'intérieur de votre classe, vous pouvez contrôler la façon dont votre événement délégués sont traitées, cependant, votre classe ne peut pas contrôler ce que la classe de base est en train de faire. Il pourrait faire un peu fou de derrière-le-scènes des trucs avec de l'événement et de ses gestionnaires. Si vous avez tout simplement "réaffectés" l'événement Move, vous serait l'anéantissement de la multidiffusion liste des délégués pour l'événement.
Je devine qu'ils ont mis un compilateur restriction sur ce parce que c'est un très pratique dangereuse, et essentiellement à donner à tout descendant de la classe de la capacité de détruire le modèle d'événement de son parent.
OriginalL'auteur womp
Vous avez seulement besoin du code que vous avez posté dans la classe où l'événement lui-même est défini. Toutes les classes dérivées doivent appelez simplement OnShapeChanged() ou OnMove() directement, sans le copier, etc., donc, vous ne devriez pas écrire ce code dans vos classes (depuis le transfert de l'événement est défini dans la base).
Si vous avez besoin de faire une sorte de traitement dans la classe dérivée (peut-être vous avez besoin de jouer avec votre collection de classe?), vous remplacez le virtuel OnXXX appel et avez-vous des trucs avant d'appeler la base.OnXXX(). Dans l'article MSDN, le Cercle classe correspond à votre DockedToolWindow classe. La même tendance devrait être à la disposition de vos classes dérivées.
OriginalL'auteur David Pope