Для передачи функции в качестве параметра в C # используется делегат .Делегат указывает ожидаемый тип возвращаемого значения и аргументы функции, передаваемой в метод, и ваш метод обратного вызова должен соответствовать этой спецификации, иначе ваш код не будет компилироваться.
Делегаты обычно объявляются непосредственно в пространстве имен и принимаютформа:
<access modifier(s)> delegate <return type> <DelegateName>([argument list]);
Например, в C # делегат с именем FooCallback, представляющий функцию обратного вызова для метода Foo, который не принимает аргументов и возвращает void, будет выглядеть так:
namespace Demo
{
public delegate void FooCallback();
}
Функция, которая принимает параметр FooCallback, будет выглядеть следующим образом:
namespace Demo
{
//delegate for a FooCallback method from the previous code block
public delegate void FooCallback();
public class Widget
{
public void BeginFoo(FooCallback callback)
{
}
Предполагая, что у вас есть метод, который соответствует сигнатуре делегата, вы можете просто передать его имя в качестве значенияпараметр делегата.Например, если у вас есть функция с именем MyFooCallback
, вы можете передать ее в качестве параметра методу StartFoo
следующим образом:
using Demo; //Needed to access the FooDelegate and Widget class.
namespace YourApp
{
public class WidgetUser
{
private Widget widget; //initialization skipped for brevity.
private void MyFooCallback()
{
//This is our callback method for StartFoo. Note that it has a void return type
//and no parameters, just like the definition of FooCallback. The signature of
//the method you pass as a delegate parameter MUST match the definition of the
//delegate, otherwise you get a compile-time error.
}
public void UseWidget()
{
//Call StartFoo, passing in `MyFooCallback` as the value of the callback parameter.
widget.BeginFoo(MyFooCallback);
}
}
}
Хотя можно определить делегата с аргументами, этоневозможно передать список аргументов вместе с именем метода, как это обычно делается при вызове метода
namespace Demo
{
public delegate void FrobCallback(int frobberID);
//Invalid Syntax - Can't pass in parameters to the delegate method this way.
BeginFrob(MyFrobCallback(10))
}
Когда делегат задает параметры, метод, который вызывает делегат, принимает аргументы, необходимые делегату, и передает ихк методу делегата, когда он вызывается:
BeginFrob(MyFrobCallback, 10)
Затем метод BeginFrob вызовет MyFrobCallback с переданным в frobberID значением 10 следующим образом:
public void BeginFrob(FrobCallback callback, int frobberID)
{
//...do stuff before the callback
callback(frobberID);
}
Лямбда-выражения позволяют вам определять метод, в котором он используется, вместо необходимости явно объявлять его
BeginFoo((int frobberID) => {your callback code here;});
Таким образом, делегаты являются средством дляметоды, передаваемые другим методам в качестве параметров.