Anonymous inner classes en C#
Je suis dans le processus de rédaction d'un C# Guichet de la mise en œuvre dans le but d'approfondir ma connaissance de C# et de Guichet. Un des problèmes que nous sommes en cours d'exécution en est que le Guichet fait un usage intensif de anonyme intérieur des classes, et le C# n'a pas les classes internes anonymes.
Ainsi, par exemple, dans le Portillon, vous définissez un Lien comme ceci:
Link link = new Link("id") {
@Override
void onClick() {
setResponsePage(...);
}
};
Depuis Lien est une classe abstraite, il oblige le réalisateur à mettre en œuvre une méthode onClick.
Toutefois, en C#, car il n'y a pas anonyme intérieur des classes, il n'y a aucun moyen de le faire. Comme alternative, vous pouvez utiliser les événements comme ceci:
var link = new Link("id");
link.Click += (sender, eventArgs) => setResponsePage(...);
Bien sûr, il ya quelques inconvénients à cela. Tout d'abord, il peut y avoir plusieurs gestionnaires de Clic, ce qui pourrait ne pas être cool. Il ne force pas le réalisateur d'ajouter un gestionnaire d'événements Click.
Une autre option pourrait être d'avoir une fermeture de la propriété comme ceci:
var link = new Link("id");
link.Click = () => setResponsePage(...);
Cela résout le problème d'avoir plusieurs gestionnaires, mais ne peut toujours pas la force de l'implémenteur pour ajouter le gestionnaire.
Donc, ma question est, comment voulez-vous émulez quelque chose comme cela dans idiomatiques C#?
- Je ne vois pas un anonyme intérieur de la classe, dans l'exemple que vous avez donné. Si vous souhaitez la mise en œuvre de votre classe abstraite pour toujours mettre en œuvre des méthodes que vous pouvez créer une méthode abstraite dans la classe ou de l'avoir à implémenter une interface.
- il y a une ligne anonyme de classe qui hérite de
Link
et remplace laonClick
méthode. Contrairement à Java, C# ne prend pas en charge anonyme classes de dériver à partir d'un type d'utilisateur. - Dimitrov, merci pour cette remarque. Je cherchais un vrai "intérieure/imbriquée" de la classe. L'exemple fourni ressemble plus à une classe anonyme qui dérive d'une classe existante, au moins en C# lingo.
- Vieux sujet mais bon, c'est toujours là... c'est un intérieur de classe parce qu'en Java, chaque classe est soit un haut-niveau de la classe ou d'une classe imbriquée (définie à l'intérieur d'une autre classe), et qu'elle soit statique ou non statique de la classe. C'est un non-statique de la classe imbriquée, et le terme qui est intérieur de la classe.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez faire le délégué faire partie de l'constructeur de la classe Link. De cette façon, l'utilisateur devra l'ajouter.
Ensuite, vous créez une instance de cette façon:
C'est ce que je ferais:
Conserver un Lien comme une classe abstraite, l'utilisation d'une Usine d'instancier et de passer dans votre fermeture d'une méthode anonyme en tant que paramètre de l'Usine de construction de la méthode. De cette façon, vous pouvez conserver votre design original avec un Lien comme une classe abstraite, forçant la mise en œuvre à travers l'usine, et cachent encore des trace de Lien à l'intérieur de l'usine.
Voici un exemple de code:
EDIT: Fait, C'est peut être un peu plus proche de ce que vous voulez:
La beauté est-il utilise un bloc init, vous permettant de déclarer autant de facultatif implémentations des actions au sein de la classe Link que vous le souhaitez.
Voici le Lien de la classe (Avec scellé Générateur interne de la classe).
C'est proche de ce que vous cherchez, mais je pense que nous pouvons prendre une étape supplémentaire avec option arguments nommés, C# 4.0 feature. Regardons l'exemple de la déclaration de Lien avec, en option, les arguments nommés:
Pourquoi est-ce cool? Regardons la nouvelle classe Link:
À l'intérieur de la classe statique Builder, il y a une usine méthode Build qui prend en 1 paramètre requis (L'ID) et 3 paramètres facultatifs, OnClick, OnFoo et OnBar. Si ils ne sont pas affectés, la méthode de fabrique, leur donne une implémentation par défaut.
Donc dans votre constructeur de paramètre d'arguments pour le Lien, vous êtes tenu de mettre en œuvre les méthodes que vous avez besoin, sinon ils vont utiliser l'action par défaut, ce qui pourrait n'être rien.
L'inconvénient, cependant, est dans le dernier exemple, le Lien de la classe n'est pas abstrait. Mais il ne peut pas être instanciée à l'extérieur de la portée de la Liaison de la classe, parce que son constructeur est privé (Forcer l'utilisation du Constructeur de la classe à instancier Lien).
Vous pouvez également déplacer l'option paramètres dans le Lien du constructeur directement, en évitant la nécessité d'une usine complètement.
J'ai commencé ce avant @meatthew la bonne réponse - je faire presque exactement les mêmes, sauf qu' - sauf que je voudrais commencer avec une classe de base abstraite - de sorte que, si vous ne voulez pas aller à la route d'un anonyme de la mise en œuvre, vous être libre de le faire aussi.