2010-09-17 7 views
2

Je comprends les délégués comme un raccourci pour définir une classe avec une méthode mais quelle est la signification de bar2 ci-dessous? Il compile. Mais je ne peux pas voir ce qu'une classe intérieure ferait ici. Je sais qu'il me manque quelque chose, c'est pourquoi je demande (ce n'est pas un devoir, je suis au travail en ce moment).Quelle est la signification d'un délégué dans une classe?

namespace ns2 { public delegate void bar();} 
public class foo 
{ 
    private ns2.bar _callback; 
    public foo(ns2.bar callback) { _callback = callback; } 
    public void baz() { _callback(); } 
    public delegate void bar2(); 
} 

Merci!

Répondre

6

C'est simplement déclarer un type imbriqué, c'est tout. Comme c'est public, il n'y a pratiquement pas de différence entre le fait d'être déclaré dans le type et le fait d'être déclaré à l'extérieur.

D'autres classes devront s'y référer via le nom du type contenant (à moins qu'ils aient une directive using spécifiquement pour elle):

public class OtherClass 
{ 
    private void DoSomething() 
    { 
     foo.bar2 action = delegate { ... }; 
     foo f = new foo(action); 
     ... 
    } 
} 

Habituellement quand j'écris un type imbriqué, il est privé - c'est juste une classe d'aide pour la classe contenant; un détail d'implémentation. Cela ne doit pas être le cas, bien sûr, mais il devrait au moins être vrai que le type imbriqué n'a pas de sens, sauf si vous êtes en utilisant la classe externe. Par exemple, il peut s'agir d'un générateur pour la classe externe ou d'une énumération utilisée dans certains paramètres pour un appel de méthode dans la classe externe.

(Soit dit en passant, il est utile lors de l'écriture exemple de code comme celui-ci à suivre les conventions de nommage .NET même pour les noms de méta-syntaxique comme Foo et Bar. Il fait la différence entre les variables et les types plus clairs, par exemple.)

+0

Merci pour la réponse et les conseils. –

7

Les délégués ne sont pas des raccourcis pour définir une classe avec une méthode. Ils ont en fait au moins 6 méthodes (Invoke, BeginInvoke, EndInvoke, GetHashCode, Equals, ToString). Une des raisons pour lesquelles les délégués sont placés dans un type est d'éviter la pollution de l'espace de noms global. Le délégué bar2 est uniquement accessible via une référence qualifiée de foo. Cela peut être utile si bar2 est un nom qui a plusieurs significations valides et le mettre dans foo fournit le contexte nécessaire.

+0

+1, n'a pas aimé la caractérisation des délégués étant des raccourcis pour définir une classe avec une méthode non plus. Doit être un héritage de classes anonymes de Java. –

+2

Il est plus raisonnable de considérer un type de délégué comme étant une * interface * avec une méthode, IMO ... et des manières supplémentaires d'appeler cette méthode pour des opérations asynchrones. Pour moi, cela donne le "sentiment" des délégués. Par intérêt, BeginInvoke est-il garanti mais pas EndInvoke? –

+0

@Jon, 'EndInvoke' est également garanti (mise à jour de ma réponse). – JaredPar

8

Pour ajouter aux réponses de Jon et Jared, je note que la seule fois où vous définissez habituellement un délégué dans une classe est si le délégué était un détail d'implémentation privée de la classe. Il est rare et bizarre d'avoir une définition de délégué publique dans une classe.

Par exemple, considérez mon modèle préféré: une classe de base abstraite qui ne peut être étendue par des classes imbriquées privées qui sont fabriqués avec des usines:

public abstract class Animal 
{ 
    private Animal() { } // prevents subclassing from outside! 
    private sealed class Giraffe : Animal { } 
    private sealed class Leopard : Animal { } 
    public static Animal GetGiraffe() { return new Giraffe(); } 
    public static Animal GetLeopard() { return new Leopard(); } 

Supposons un détail de la mise en œuvre des animaux est que vous avez besoin d'avoir un délégué de girafe à Leopard:

private delegate Leopard D(Giraffe g); 

Cela ne peut pas être une classe de délégué du public, car il fait référence à des types particuliers!

De nos jours, bien sûr, vous ne le feriez même pas. Vous utiliseriez Func<Giraffe, Leopard> et vous avez terminé. Par conséquent, le type de délégué imbriqué est à peu près là pour l'exhaustivité et la rétrocompatibilité ces jours-ci; Normalement, vous ne l'utiliseriez pas.

Questions connexes