Что такое делегат?

Я смущен тем, что в действительности роль делегата?

Меня неоднократно задавали этот вопрос в моих интервью, но я не думаю, что интервьюеры были удовлетворены моим ответом.

Может ли кто-нибудь сказать мне лучшее определение в одном предложении с практическим примером?

Ответ 1

Мне нравится думать о делегате как "указателе на функцию". Это восходит к C-дням, но идея по-прежнему сохраняется.

Идея заключается в том, что вы должны иметь возможность ссылаться на кусок кода, но этот фрагмент кода, который вы собираетесь вызывать, неизвестен до выполнения. Таким образом, для этой цели вы используете "делегат". Делегаты пригождаются для таких вещей, как обработчики событий и т.д., Где вы делаете разные вещи, основанные на разных событиях, например.

Вот ссылка для С#, на которую вы можете посмотреть:

Например, в С# предположим, что у нас был расчет, который мы хотели сделать, и мы хотели использовать другой метод расчета, который мы не знаем до выполнения. Таким образом, у нас может быть несколько методов расчета:

public static double CalcTotalMethod1(double amt)
{
    return amt * .014;
}

public static double CalcTotalMethod2(double amt)
{
    return amt * .056 + 42.43;
}

Мы могли бы объявить подпись делегата следующим образом:

public delegate double calcTotalDelegate(double amt);

И тогда мы могли бы объявить метод, который принимает делегат как параметр, подобный этому:

public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal)
{
    return calcTotal(amt);
}

И мы могли бы вызвать метод CalcMyTotal который передается в методе делегата, который мы хотели использовать.

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);

Ответ 2

делегат - это просто указатель на функцию.
просто поставьте вам способ, которым вы хотите управлять своим делегатом. то позже в коде вы можете вызвать этот метод через Invoke.

некоторый код для демонстрации (написал это из памяти, поэтому синтаксис может быть отключен)

delegate void delMyDelegate(object o);

private void MethodToExecute1(object o)
{
    // do something with object
}

private void MethodToExecute2(object o)
{
    // do something else with object
}

private void DoSomethingToList(delMyDelegate methodToRun)
{
    foreach(object o in myList)
        methodToRun.Invoke(o);
}

public void ApplyMethodsToList()
{
    DoSomethingToList(MethodToExecute1);
    DoSomethingToList(MethodToExecute2);
}

Ответ 3

Взято отсюда

Q Что такое делегаты?
  A Когда объект получает запрос, объект может обрабатывать сам запрос или передать запрос второму объекту для выполнения работы. Если объект решает передать запрос, вы говорите, что объект передал ответственность за обработку запроса второму объекту.

Или, как простой псевдо-пример: что-то отправляет запрос объекту1. object1 затем пересылает запрос и сам объект object2 - делегат. object2 обрабатывает запрос и выполняет некоторую работу. (примечание: ссылка выше дает хорошие примеры)

Ответ 4

Подумайте об делегате как об упрощенной реализации шаблона Command.

Ответ 5

Делегат - это объект, который может ссылаться на метод. Таким образом, когда мы создаем делегат, мы создаем объект, который может содержать ссылку на метод. Кроме того, этот метод можно вызвать через эту ссылку. Таким образом, делегат может ссылаться на метод, к которому он относится. Основное преимущество делегата состоит в том, что он позволяет нам указывать вызов метода, но фактически используемый метод определяется во время выполнения, а не во время компиляции.

Простой делегат

Declaration of delegate:
delegate-modifier delegate return-type delegate-name(parameters)
Implementation of delegate:
Delegate-name delegate-object=new Delegate-name(method of class)

http://knowpacific.wordpress.com/2012/01/26/delegate/

Ответ 6

Здесь я собираюсь объяснить делегатов, делегатов многоадресной рассылки и их использования. Делегат - это тип, который содержит ссылку метода (методов) в объекте. Он также упоминается как указатель функции безопасного типа. Мы можем сказать, что делегат - это тип, определяющий подпись метода.

Когда вы создаете экземпляр делегата, вы можете связать его экземпляр любым способом с совместимой сигнатурой. Вы можете вызвать (или вызвать) метод через экземпляр делегата. Делегаты используются для передачи методов в качестве аргументов другим методам. Обработчики событий - это не что иное, как методы, вызываемые через делегатов. Преимущества использования делегатов,   Инкапсуляция вызова метода от вызывающего   Эффективное использование делегата повышает эффективность применения   Используется для вызова метода асинхронно. Есть некоторые свойства делегатов:

Delegates are like C++ function pointers but are type safe.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
Delegates can be chained together; for example, multiple methods can be called on a single event.
Methods do not have to match the delegate signature exactly.

public delegate type_of_delegate delegate_name()//Декларация

You can use delegates without parameters or with parameter list
If you are referring to the method with some data type then the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer. Here I am giving an example with String.

В следующем примере показана операция делегата:

    namespace MyDelegate
    {
        class Program
        {
            private delegate void Show(string s);


            // Create a method for a delegate.
            public static void MyDelegateMethod(string me

ssage)
        {
            System.Console.WriteLine(message);
        }

        static void Main(string[] args)
        {
            Show p = MyDelegateMethod;
            p("My Delegate");
            p.Invoke("My Delegate");
            System.Console.ReadLine();
        }
    }
}

Что такое многоадресный делегат?

Это делегат, который содержит ссылку более чем на один метод. Многоадресные делегаты должны содержать только методы, возвращающие void, иначе существует исключение во время выполнения.

 delegate void MyMulticastDelegate(int i, string s);
 Class Class2
 {
  static void MyFirstDelegateMethod(int i, string s)
  {
    Console.WriteLine("My First Method");
  }

  static void MySecondDelegateMethod(int i, string s)
  {
    Console.WriteLine("My Second Method");
  }

  static void Main(string[] args)
  {
    MyMulticastDelegate Method= new MyMulticastDelegate(MyFirstDelegateMethod);
    Method+= new MyMulticastDelegate (MySecondDelegateMethod);
    Method(1,"Hi");             // Calling 2 Methodscalled
    Method-= new MyMulticastDelegate (MyFirstDelegateMethod);
    Method(2,"Hi");             //Only 2nd Method calling
  }
}

Здесь делегат добавляется с помощью оператора + = и удаляется с помощью оператора - =.

Типы делегатов выводятся из класса Delegate в .NET Framework. Типы делегатов запечатаны - они не могут быть получены. Поскольку созданный экземпляр делегата является объектом, его можно передать как параметр или присвоить свойству. Это позволяет методу принять делегат в качестве параметра и вызвать делегата через некоторое время. Это называется асинхронным обратным вызовом.

Ответ 7

Большое объяснение и практическая реализация шаблона Delegate можно найти в коллекциях Google Forwarding (также, рисунок Decorator).

Ответ 8

В сообщении отправителя событий не известно, какой объект будет обрабатывать событие. Делегат - это тип, который содержит ссылку на метод. Делегат имеет подпись и имеет ссылку на метод, который соответствует его подписи поэтому делегат - это как указатель функции безопасного типа.

button1.Click + = новый System.EventHandler(button1_Click) System.EventHandler объявлен как делегат здесь В .net События работают над концепцией делегата (например, кнопкой)

Делегат используется, когда вы не знаете, какой код вызывать во время выполнения Поэтому в это время делегат используется для обработки событий

http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx

Ответ 9

Делегаты в основном используются с событиями.

Необходимость:

Вы не хотите выполнять часть кода в момент запуска программы. После запуска программы вы хотите выполнить этот фрагмент кода всякий раз, когда происходит событие.

Пример:

  • Консольное приложение - код может быть выполнен только во время запуска программы. (Написан внутри основного метода)
  • Приложение Windows (программирование пользовательского интерфейса) - код может быть запущен при нажатии кнопки после запуска программы.

Это то, что они говорят, вы не знаете, какой метод будет вызывать при компиляции. вы знаете это только во время выполнения, когда вы нажимаете кнопку.

Без делегатов невозможно программирование пользовательского интерфейса. Поскольку вы выполняете код всякий раз, когда пользователь делает события, которые нажимают кнопку, вводя текстовое поле, выбирая элемент списка и т.д....

Ответ 10

A объект делегирования это объект, с которым обращается другой объект, когда что-то происходит в этом объекте. Для Например, ваш ремонтник является вашим делегатом, если что-то случится с вашим автомобилем. вы обратитесь к своему ремонту и попросите его исправить машину для вас (хотя некоторые предпочитают сами ремонтировать автомобиль, и в этом случае они являются их собственным делегатом для своей машины).

Ответ 11

Делегат - это объект, представляющий указатель на функцию. Однако он не является обычным указателем функции, поскольку он:

1) Объектно-ориентированный

2) Безопасен тип, т.е. он может указывать только на метод, и вы не можете прочитать необработанный адрес памяти, на который он указывает

3) Является строго типизированным. Он может указывать только на методы, соответствующие его сигнатурам.

4) Можно одновременно указать несколько методов.

Ответ 12

Делегат - это то, на что делегируется задача. Основная цель делегирования - разделить код и обеспечить большую гибкость и повторное использование.

В программировании и, в частности, объектно-ориентированном программировании это означает, что когда метод вызывается для выполнения некоторой работы, он передает работу методу другого объекта, к которому имеет ссылку. Ссылка может указывать на любой объект, который мы желаем, до тех пор, пока объект соответствует предопределенному набору методов. Мы называем это "программированием для интерфейса" (от программирования до конкретной реализации класса). Интерфейс в основном является общим шаблоном и не имеет реализации; это просто означает рецепт, набор методов, предпосылок и постусловий (правил).

Простой пример:

SomeInterface
{
   public void doSomething();
}


SomeImplementation implements SomeInterface
{
   public void doSomething()
   {
      System.err.println("Was it good for you?");
   }

}


SomeCaller
{
   public void doIt(SomeInterface someInterface)
   {
      someInterface.doSomething();
   }
}

Теперь вы видите, что я могу использовать любую реализацию, которую я хочу в любое время, без изменения кода в SomeCaller, потому что тип, который передается doIt(), не является конкретным, а довольно абстрактным, поскольку это интерфейс. В мире Java это часто выражается в парадигме обслуживания, где вы обращаетесь к службе (объект, рекламирующий себя как услугу через определенный интерфейс), и служба затем обращается к делегатам, чтобы помочь ему выполнить свою работу. Методы службы называются крупнозернистыми задачами (makePayment(), createNewUser() и т.д.), Тогда как внутри он делает много, если nitty-grritty работает через делегирование, причем типы делегатов являются интерфейсами вместо конкретных реализаций.

SomeService
{
    SomeInterface someImplementation = ... // assign here
    SomeOtherInterface someOtherImplementation = ... // okay, let add a second

    public void doSomeWork()
    {
         someImplementation.doSomething();
         someOtherImplementation.doSomethingElse();
    }
}

(N.B.: Как назначается реализация, выходит за рамки этого потока. Инверсия запроса на управление и зависимость).

Ответ 13

Хотя это не действительно "указатель функции", делегат может выглядеть так: динамический язык, такой как PHP:



$func = 'foo';
$func();

function foo() {
    print 'foo';
}

или в JavaScript вы можете сделать что-то вроде:


var func = function(){ alert('foo!'); }
func();