Pregunta

Por favor alguien puede romper lo que es un delegado en un simple, conciso y breve explicación que abarca tanto el propósito y los beneficios generales? He tratado de envolver mi cabeza alrededor de esto y es simplemente no se hunde en.

¿Fue útil?

Solución

En los términos más simples posibles, que es esencialmente un puntero a un método.

Se puede tener una variable que contiene un tipo de delegado (al igual que tendría una variable int que puede contener un tipo int). Puede ejecutar el método que los puntos de delegados a simplemente llamando a la variable como una función.

Esto le permite tener funciones variables al igual que es posible que tenga datos variables. Su objeto puede aceptar delegados de otros objetos y llamar a ellos, sin tener que definir todas las posibles funciones en sí.

Esto es muy útil cuando se desea un objeto de hacer las cosas en función de criterios especificados por el usuario. Por ejemplo, el filtrado de una lista basada en una falsa expresión definida por el usuario verdadero /. Puede dejar que el usuario especifique la función de delegado para su uso como un filtro para evaluar cada elemento de la lista en contra.

Otros consejos

Tengo una función:

public long GiveMeTwoTimesTwo()
{
    return 2 * 2;
}

Esta función aspira. ¿Y si quiero 3 * 3?

public long GiveMeThreeTimesThree()
{
    return 3 * 3;
}

El exceso de escribir. Soy un vago!

public long SquareOf(int n)
{
    return n * n;
}

Mi función SquareOf no le importa lo que es n. Si funcionará correctamente para cualquier n se ha pasado. No se sabe exactamente qué número es n, pero no sabe que n es un entero. No se puede pasar "Haha not an integer" en SquareOf.

Aquí hay otra función:

public void DoSomethingRad()
{
    int x = 4;
    long y = SquareOf(x);
    Console.WriteLine(y);
}

Contrariamente a su nombre, DoSomethingRad en realidad no hacer nada rad. Sin embargo, lo hace escribir el SquareOf (4), que es 16. Podemos cambiar a ser menos aburrido?

public void DoSomethingRad(int numberToSquare)
{
    long y = SquareOf(numberToSquare);
    Console.WriteLine(y);
}

DoSomethingRad es evidente que aún bastante fallar. Pero al menos ahora podemos pasar a un número cuadrado, por lo que no escribirá 16 cada vez. (Se va a escribir 1 o 4, o 9, o 16, o ... zzzz todavía un poco aburrido).

Sería bueno si había una manera de cambiar lo que ocurre con el número aprobada en Tal vez no queremos que cuadrar.; tal vez queremos al cubo, o restarlo de 69 (número elegido al azar de la cabeza).

En una inspección posterior, parece como si la única parte de SquareOf que se preocupa DoSomethingRad es de que podemos darle un número entero (numberToSquare) y que nos da una long (porque ponemos su valor de retorno en y y y es un long).

public long CubeOf(int n)
{
    return n * n * n;
}

public void DoSomethingLeet(int numberToSquare)
{
    long y = CubeOf(numberToSquare);
    Console.WriteLine(y);
}

Vea cómo similares DoSomethingLeet es DoSomethingRad? Si sólo había una manera de pasar en Comportamiento (DoX()) en lugar de sólo datos (int n) ...

Así que ahora si queremos escribir una cuadrada de un número, podemos DoSomethingRad y si queremos escribir el cubo de un número, podemos DoSomethingLeet. Así que si queremos escribir el número restado de 69, tenemos que hacer otro método, DoSomethingCool? No, porque eso lleva demasiado maldito mucho escribiendo (y más importante, que dificulta nuestra capacidad de comportamiento interesante alter cambiando sólo un aspecto de nuestro programa).

Así se llega a:

public long Radlicious(int doSomethingToMe, Func<int, long> doSomething)
{
    long y = doSomething(doSomethingToMe);
    Console.WriteLine(y);
}

Nos puede llamar a este método escribiendo esto:

Radlicious(77, SquareOf);

Func<int, long> es un tipo especial de delegado. Almacena comportamiento que acepta números enteros y escupe longs. No estamos seguros de lo que el método que apunta a que va a hacer con cualquier número entero dado que pasamos; todo lo que sabemos es que, pase lo que pase, vamos a obtener una copia de long.

No tenemos que dar ningún parámetro a SquareOf porque Func<int, long> describe Comportamiento , no datos. Llamando Radlicious(77, SquareOf) apenas da Radlicious el comportamiento general de SquareOf ( "Tomo un número y su cuadrado regreso"), no lo va a hacer SquareOf a cualquier específica entero.

Ahora bien, si usted ha entendido lo que estoy diciendo, entonces usted tiene ya me al próximo nivel, porque yo mismo realmente no obtener estas cosas.

RESPUESTA * sentido, iniciar VAGA IDIOTEZ *

Es decir, parece que ints podrían percibirse como un comportamiento realmente aburrido:

static int Nine()
{
    return 9;
}

Dicho esto, la línea entre lo que es de datos y el comportamiento parece diluir, con lo que normalmente se percibe como datos es simplemente aburrido-culo comportamiento.

Por supuesto, uno podría imaginar el comportamiento súper "interesante", que se lleva a todo tipo de parámetros abstractos, sino que requiere una gran cantidad de información para poder llamarlo. ¿Y si nos requiere para proporcionar el código fuente que sería compilar y ejecutar para nosotros?

Bueno, entonces nuestra abstracción parece que nos ha metido toda la parte posterior forma de un cuadrado. Tenemos un comportamiento tan abstracto que requiere todo el código fuente de nuestro programa para determinar lo que va a hacer. Esto es totalmente indeterminada behavior: la función se puede hacer lo , pero tiene que estar dotado de todo para determinar lo que hace. Por otra parte, totalmente comportamiento en concreto, como Nine(), no necesita ninguna información adicional, pero no puede hacer otra cosa que no sea 9 retorno.

Entonces, ¿qué? No sé.

Un delegado es un puntero a un método. A continuación, puede utilizar su delegado como un parámetro de otros métodos.

aquí es un enlace a una explicación sencilla.

La pregunta que tenía era 'Por lo tanto, ¿por qué iba yo a querer hacer eso?' Realmente no se 'conseguirlo' hasta que resuelva un problema de programación con ellos.

Es interesante que nadie ha mencionado uno de los beneficios clave de delegación - es preferible a subclasificar cuando se da cuenta de que la herencia no es una varita mágica y por lo general crea más problemas de los que resuelve. Es la base de muchos patrones de diseño, sobre todo el estrategia patrón.

Una instancia de delegado es una referencia a un método. La razón por la que son útiles es que se puede crear un delegado que está ligado a un método particular en un caso particular de un tipo. La instancia de delegado le permite invocar ese método en ese caso concreto, incluso si el objeto en el que se invoca el método ha salido de su ámbito léxico.

El uso más común para casos como este delegado es apoyar el concepto de devoluciones de llamada en el nivel de idioma.

Simplemente hace referencia a un método. Vienen en gran uso en el trabajo con las roscas.

Este es un ejemplo correcto de mi código.

 //Start our advertisiment thread
    rotator = new Thread(initRotate);
    rotator.Priority = ThreadPriority.Lowest;
    rotator.Start();

    #region Ad Rotation
    private delegate void ad();
    private void initRotate()
    {
        ad ad = new ad(adHelper);
        while (true)
        {
            this.Invoke(ad);
            Thread.Sleep(30000);
        }

    }

    private void adHelper()
    {
        List<string> tmp = Lobby.AdRotator.RotateAd();
        picBanner.ImageLocation = @tmp[0].ToString();
        picBanner.Tag = tmp[1].ToString();            
    }
    #endregion

Si no usamos un delegado que no sería capaz de desgarre y llamar a la función Lobby.AdRotator.

Al igual que otros han dicho, un delegado es una referencia a una función. Uno de los usos más beneficiosos (IMO) es eventos. Cuando se registra un evento registra una función para el evento de invocar, y los delegados son perfectos para esta tarea.

En los términos más básicos, un delegado es simplemente una variable que contiene (en referencia a) una función. Los delegados son útiles porque permiten pasar de una función alrededor como una variable sin ninguna preocupación por "donde" la función en realidad procedían de.

Es importante tener en cuenta, por supuesto, que la función no está siendo copiado cuando se está envuelto en una variable; Simplemente ha de ser obligado por referencia. Por ejemplo:

class Foo
{
    public string Bar
    {
        get;
        set;
    }

    public void Baz()
    {
        Console.WriteLine(Bar);
    }
}

Foo foo = new Foo();
Action someDelegate = foo.Baz;

// Produces "Hello, world".
foo.Bar = "Hello, world";
someDelegate();

En la mayoría de los términos más simples, la responsabilidad de ejecutar un método se delega a otro objeto. Digamos que el presidente de algunas matrices nación y el presidente de EE.UU. se supone que debe estar presente para el funeral con el mensaje de condolencias. Si el presidente de EE.UU. no es capaz de ir, va a delegar esta responsabilidad a otra, ya sea el vicepresidente o el secretario del estado.

Lo mismo pasa en el código. Un delegado es un tipo, es un objeto que es capaz de ejecutar el método.

por ejemplo.

Class Person
{
   public string GetPersonName(Person person)
   {
     return person.FirstName + person.LastName;
   }

   //Calling the method without the use of delegate
   public void PrintName()
   {
      Console.WriteLine(GetPersonName(this));
   }

   //using delegate
   //Declare delegate which matches the methods signature
   public delegate string personNameDelegate(Person person);

  public void PrintNameUsingDelegate()
  {
      //instantiate
      personNameDelegate = new personNameDelegate(GetPersonName);

      //invoke
      personNameDelegate(this);
  }

}

El método GetPersonName se llama usando el personNameDelegate objeto delegado. Como alternativa podemos tener el método PrintNameUsingDelegate tomar un delegado como parámetro.

public void PrintNameUsingDelegate(personNameDelegate pnd, Person person)
{
   pnd(person);
}

La ventaja es que si alguien desea imprimir el nombre como lastname_firstname, él / ella sólo tiene que concluir que el método de personNameDelegate y pasar a esta función. No se requiere un código adicional.

Los delegados son específicamente importante en

  1. Eventos
  2. asincrónica llama
  3. LINQ (como expresiones lambda)

Si se va a delegar una tarea a otra, el delegado sería la persona que recibe el trabajo.

En la programación, es una referencia al bloque de código que realmente sabe cómo hacer algo. A menudo esto es un puntero a la función o método que se encargará de algún artículo.

En la mayoría de los absolutos términos más simples que puede llegar a es la siguiente: Un delegado obligará a las cargas de trabajo en manos de una clase que más o menos sabe qué hacer. Piense en ello como un niño que no quiere crecer para ser como su hermano mayor por completo, pero todavía necesita su guía y órdenes. En lugar de heredar todos los métodos de su hermano (es decir, la subclasificación), que sólo hace que su hermano haga el trabajo o el hermano pequeño hace algo que requiere de acciones a ser tomadas por el hermano mayor. Cuando se cae en las líneas de protocolos, los grandes define hermano lo que es absolutamente necesario, o que podrían darle flexibilidad de elegir lo que quiere hacer que él hace en ciertos eventos (es decir, protocolos informales y formales como se indica en Objective-C).

El beneficio absoluto de este concepto es que no es necesario crear una subclase. Si quieres algo que caer en línea, sigue las órdenes cuando un evento ocurre, el delegado permite una clase desarrollada para sostenerlo de la mano y dar órdenes si es necesario.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top