Функция как аргумент метода - PullRequest
2 голосов
/ 23 августа 2010

Вы можете выполнять анонимные функции в C # так же, как в JavaScript:

JavaScript:

var s = (function ()
{
    return "Hello World!";
}());

C #:

var s = new Func<String>(() =>
{
    return "Hello World!";
})();

... В JavaScript вы можете передавать функции, которые будут выполняться другими функциями. Более того; Вы можете передать параметры в функцию, которая будет выполнена:

var f = function (message) // function to be executed
{
    alert(message);
};

function execute(f) // function executing another function
{
    f("Hello World!"); // executing f; passing parameter ("message")
}

Возможен ли приведенный выше пример в C #?


Обновление

Вариант использования: я перебираю кучу баз данных, регистрирую конкретные сущности. Вместо того чтобы вызывать мою вторую функцию (F()) внутри Log() из Logger, я бы хотел вызвать F() вне класса.

... Что-то вроде:

public void F(String databaseName)
{
}

public class Logger
{
    public void Log(Function f)
    {
        var databaseName = "";

        f(databaseName);
    }
}

Ответы [ 4 ]

6 голосов
/ 23 августа 2010

Абсолютно - вам просто нужно дать методу соответствующую подпись:

public void Execute(Action<string> action)
{
    action("Hello world");
}
...
Execute(x => Console.WriteLine(x));

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

РЕДАКТИРОВАТЬ: Ваш пример базы данных точно такой же, как этот - вы хотите передать строку и не получить никакого вывода, что и делает Action<string>. За исключением случаев, когда вы пытаетесь вызвать существующий метод (F() в вашем коде), вам даже не нужно лямбда-выражение - вместо этого вы можете использовать преобразование группы методов:

public void F(String databaseName)
{
}

public class Logger
{
    public void Log(Action<string> f)
    {
        var databaseName = "";

        f(databaseName);
    }
}

// Call it like this:
Logger logger = new Logger(...);
logger.Log(F);
1 голос
/ 23 августа 2010

согласно вашей части обновления: вам нужен контейнер, чтобы сохранить ваши функции

 IList<Action<string>> actionList = new List<Action<Sstring>>();

в вашей функции Log () вы можете добавить F () в контейнер:

actionList.Add(F);

затем вызовите функцию (и) где-нибудь за пределами:

 foreach (Action<string> func in actionList)
      {
           func("databasename");
      }
1 голос
/ 23 августа 2010

Вы можете передать делегату:

        var f = (Action<string>)
                (x =>
                     {
                         Console.WriteLine(x);
                     }
                );

        var execute = (Action<Action<string>>)
                      (cmd =>
                           {
                               cmd("Hello");
                           }
                      );
        execute(f);
0 голосов
/ 23 августа 2010

Как:

var s = new Func<String, string>((string name) =>
{
    return string.Format("Hello {0}!", name);
});

...