38 votes

Mot-clé délégué vs. délégué

Si vous souhaitez créer des délégués personnalisés, vous devez utiliser le mot clé delegate en minuscules.

Que pouvez-vous faire avec la classe de délégués actuelle ? À quoi cela sert-il ? Je ne comprends pas la différence exacte.

38voto

Gishu Points 59012

Le mot-clé "délégué" permet au compilateur de faire un peu de magie pour vous. Lorsque vous déclarez un nouveau délégué avec une signature personnalisée,

  • le compilateur crée pour vous un nouveau type dérivé de MulticastDelegate (qui dérive à son tour de Delegate).
  • le compilateur ajoute une méthode Invoke avec votre signature personnalisée
  • De même, le compilateur ajoute les méthodes BeginInvoke et EndInvoke pour ce nouveau type.

Donc maintenant, quand vous appelez delObject(args) - le compilateur traduit cela en delObject.Invoke(args)

La classe de base Delegate fournit certaines fonctionnalités telles que

  1. CreateDelegate (pour obtenir un délégué enveloppant une méthode statique/instance)
  2. DynamicInvoke (pour invoquer un délégué avec une liste d'arguments - late bound)
  3. Combiner et supprimer (pour le chaînage de délégués enchaîner plusieurs délégués ensemble, par exemple plusieurs délégués de traitement d'événement pour un événement)

Le compilateur C# vous interdit de dériver de Delegate de manière explicite dans votre code vous devez utiliser le mot clé delegate.

36voto

LukeH Points 110965

Desde http://msdn.microsoft.com/en-us/library/system.delegate.aspx :

El Delegate est la classe de base pour les types de délégués. Cependant, seuls le système et les compilateurs peuvent dériver explicitement de la classe Delegate ou de la MulticastDelegate la classe. Il est n'est pas non plus autorisé à dériver un nouveau type à partir d'un type délégué. Le site Delegate n'est pas considérée comme un type de délégué ; c'est une classe utilisée pour dériver des types de délégués.

La plupart des langages implémentent un delegate mot-clé, et les compilateurs de ces sont capables de dériver du mot-clé MulticastDelegate par conséquent, les utilisateurs doivent utiliser la delegate mot-clé fourni par la langue.

3voto

galets Points 4119

Une autre chose intéressante que vous pouvez faire avec delegate est de créer des délégués en ligne, sans avoir à les déclarer, par exemple :

// constructor
public Form1()
{
    this.Load += delegate(object sender, EventArgs e)
    {
         // Form1_Load code goes right here
    }
}

2voto

JaredPar Points 333733

L'avantage de la classe Delegate est qu'elle est la classe de base pour tous les types de délégués dans .Net. Le fait d'avoir une méthode qui prend une instance de cette classe vous permet d'opérer de manière générique sur toutes sortes de délégués. C'est la raison pour laquelle des opérations comme ISynchronizedInvoke.Invoke l'utilisent comme paramètre.

2voto

Dan Points 3922

Une des choses que le Delegate peut être utilisée pour obtenir un meilleur contrôle lors de l'appel de gestionnaires d'événements. Par exemple, avec le traitement normal des événements, une exception dans un gestionnaire d'événements empêchera l'appel de tout autre gestionnaire d'événements ultérieur. Vous pouvez modifier ce comportement en utilisant la classe Delegate pour invoquer manuellement chaque gestionnaire d'événement.

using System;

namespace DelegateClass
{
    class EventSource
    {
        public event EventHandler TheEvent;

        internal void RaiseEvent1()
        {
            EventHandler handler = TheEvent;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        internal void RaiseEvent2()
        {
            EventHandler handler = TheEvent;
            if (handler == null)
                return;

            Delegate[] handlers = handler.GetInvocationList();
            foreach (Delegate d in handlers)
            {
                object[] args = new object[] { this, EventArgs.Empty };
                try
                {
                    d.DynamicInvoke(args);
                }
                catch (Exception ex)
                {
                    while (ex.InnerException != null)
                        ex = ex.InnerException;

                    Console.WriteLine(ex.Message);
                }
            }
        }
    }

    class Program
    {
        static void Handler1(object sender, EventArgs e)
        {
            Console.WriteLine("Handler1");
        }

        static void Handler2(object sender, EventArgs e)
        {
            Console.WriteLine("Handler2");
            throw new InvalidOperationException();
        }

        static void Handler3(object sender, EventArgs e)
        {
            Console.WriteLine("Handler3");
        }

        static void Main(string[] args)
        {
            EventSource source = new EventSource();
            source.TheEvent += Handler1;
            source.TheEvent += Handler2;
            source.TheEvent += Handler3;

            try
            {
                source.RaiseEvent1();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("-------------------");

            source.RaiseEvent2();
        }
    }
}

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