2 votes

Pourquoi déclarer Delegate<T> à l'intérieur de Class<T> génère-t-il un avertissement dans VS ?

Il y a beaucoup de discussions sur la question de savoir s'il faut fortement taper les arguments d'événement. Cette question ne concerne pas cela. J'ai la classe suivante (seul le code pertinent est inclus):

public abstract class Thread:
    System.IDisposable
    where TSender: Thread, new()
    where TEventArgs: System.EventArgs, new()
{
    public delegate void ThreadEventHandler (Thread sender, ThreadEventArgs e);

    // This declaratino generates a VS 2012 warning.
    public delegate void ThreadProcessIterationEventHandler (TSender sender, TEventArgs e);
}

La déclaration du deuxième délégué génère des avertissements VS2012 :

1. Le paramètre de type 'TSender' a le même nom que le paramètre de type du type extérieur 'Thread'

2. Le paramètre de type 'TEventArgs' a le même nom que le paramètre de type du type extérieur 'Thread'

Cette structure semble logiquement correcte puisque l'intention est de fournir un mécanisme d'exécution de threads encapsulé pour les classes dérivées. C'est certainement du code légal et il se compile et s'exécute comme prévu.

J'aurais pensé que avoir une contrainte de pointage vers soi-même pourrait être considéré comme une mauvaise pratique, mais pourquoi TSender et TEventArgs sont-ils signalés comme avertissements? N'est-ce pas la même chose que de déclarer NestedClass?

Devrais-je être à l'affût de quelque chose?

MISE À JOUR : Le but du deuxième délégué est de permettre aux classes enfants de déclencher des événements fortement typés.

9voto

Reed Copsey Points 315315

Vous déclarez un délégué, avec de nouveaux spécificateurs de type. Vous pouvez déclarer ceci sans les types génériques supplémentaires :

public delegate void ThreadProcessIterationEventHandler(TSender sender, TEventArgs e);

En mettant dans la déclaration du délégué, cela définit de nouveaux types à utiliser dans le délégué, avec le même nom que le type générique contenant. C'est comme si vous écriviez :

public delegate void ThreadProcessIterationEventHandler(TFoo sender, TBar e);

Essentiellement, en ajoutant ces types, vous permettez en fait au délégué de fonctionner avec des types différents de la classe contenant. Puisque vous avez utilisé les mêmes noms, le compilateur suppose qu'il s'agit d'une erreur et vous avertit.

6voto

Jon Skeet Points 692016

C'est la deuxième déclaration qui échoue :

ThreadProcessIterationEventHandler(...)

Vous ne pouvez pas déclarer un nouveau paramètre de type appelé TSender dans un type qui déclare déjà un paramètre de type TSender.

Vous ne voulez pas un nouveau type générique cependant - vous voulez simplement réutiliser les paramètres de type du type englobant :

public delegate void ThreadProcessIterationEventHandler(TSender sender, TEventArgs e);

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