Другие языки программирования и технологии

Хочу разобраться с Делегатами в С# - нужен совет знающего и какой-то немудреный пример, помогите, кто шарит!!

Serik Begmatov
Serik Begmatov
125
Если ты уже учил С++,то делегат-это аналог указателя на ф-цию, только более навороченный. Так как С# полностью объектно-ориентированыый, то и делегат-это объект класса. Он хранит адрес вызываемой ф-ции, а так же имеет средства для синхронного и асинхронного (в другом потоке) вызыва ф-ции, на которую он ссылается. А также он может вызывать не только одну ф-цию, но и цепочку ф-ций. Рассмотрим самый простой пример.
public delegete int MyHandler(int x,bool f);
Этой записью мы описали класс делегата, который может ссылаться на ф-цию, принимающую два параметра: int и bool,и возвращающей int.
Если взглянуть на сенерированный промежуточный код CIL сборки в Ildasm или Reflector,то вместо этой записи мы увидим обычное описание класса. Там есть конструктор, который принимает адрес ф-ции. А так же есть три метода:
public int Invoke(int x,bool f);
public IAsyncResult BeginInvoke(int x,bool f,AsyncCallback cb,object state);
public int EndInvoke(IAsyncresult reult);

Первый метод нужен для для синхронного вызова метода, два других, для асинхронного метода.
Используем делегат так. Пусть у нас есть ф-ция
int Func(int x,bool f)
{
if(f==true)
return x+x;
else
return x*x;
}
Применим делегат
MyHandler h=new MyHandler(Func);
Так мы создали экземпляр делегата и указали. что через него будет вызываться Func().
Применим наш делегат
int res=h(10,true); //равносильно h.Invoke(10,true); получим 20
res=h(10,false); //получим 100

Здесь возникает вопрос, а нафига это нужно, если мы могли просто написать
int res=Func(10,true);
и получим тот же результат, не заморачиваясь с делегатом? Ответ кроется в возможности асинхронного вызова делегата.
При асинхронном вызове из пула рабочих потоков берётся поток и наша ф-ция выполняется в отдельном потоке, а программа продолжает работать, не дожидаясь завершения работы этой ф-ции.
Но это довольно обширная тема и её здесь в двух словах не опишешь.
Так же делегаты нужны для отработки событий. Они передаются событию и определяют, какая ф-ция должна быть вызвана при возникновении этого события.
АШ
Алексей Шамаев
9 759
Лучший ответ
ох я тоже хочу ))))
delegate int MyFunction(int x);
delegate void MyProcedure();

int Sample1(MyFunction function, int param)
{
return function(param) + 1;
}

void Sample2(MyProcedure procedure, int count)
{
for (int i = 0; i < count; i++)
procedure();
}

C#3:

MyFunction function = x => x * 2;
Console.Write(Sample1(function, 1)); // 3

var y = 1;
MyProcedure procedure = () => y += 2;
Sample2(procedure, 5);
Console.WriteLine(y); // 11

C#2:

MyFunction function = delegate(int x) { return x * 2; };
Console.Write(Sample1(function, 1)); // 3

var y = 1;
MyProcedure procedure = delegate() { y += 2; };
Sample2(procedure, 5);
Console.WriteLine(y); // 11

MyProcedure hallo_world = delegate() { Console.WriteLine("Hallo"); };
hallo_world += delegate() { Console.WriteLine("World"); };

hallo_world(); // Hallo\nWorld

Это основное.
Делегаты можно создавать из любых методов управляемых типов: закрытых, статичных, абстрактных и т. д. При этом в нестатичных методах доступ к нестатичным членам объекта не будет как-либо ограничен (т. е. this работает) . Например, метод Thread.Start принимает в качестве параметра делегат - метод, который должен выполняться в новом потоке.