cllpse
cllpse

Reputation: 21727

Function as an argument to a method

You can do anonymous functions in C# like you can in JavaScript:

JavaScript:

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

C#:

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

... In JavaScript you can pass functions to be executed by other functions. On top of that; you can pass parameters to the function which gets executed:

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")
}

Is the above example possible in C#?


Update

Use-case: I am iterating over a bunch of database, logging specific entities. Instead of calling my second function (F()) inside Log() of Logger, I'd like to call F() outside the class.

... Something along the lines of:

public void F(String databaseName)
{
}

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

        f(databaseName);
    }
}

Upvotes: 2

Views: 206

Answers (4)

Arseny
Arseny

Reputation: 7351

according your Update part: you need a container to keep your functions

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

in your Log() function you can add your F() to the container:

actionList.Add(F);

then invoke the function(s) somewhere outside:

 foreach (Action<string> func in actionList)
      {
           func("databasename");
      }

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1499770

Absolutely - you just need to give the method an appropriate signature:

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

Note that you do have to specify the particular delegate type in the parameter - you can't just declare it as Delegate for example.

EDIT: Your database example is exactly the same as this - you want to pass in a string and not get any output, which is exactly what Action<string> does. Except if you're trying to call an existing method (F() in your code) you don't even need a lambda expression - you can use method group conversions instead:

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);

Upvotes: 6

desco
desco

Reputation: 16782

You can pass delegate:

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

        var execute = (Action<Action<string>>)
                      (cmd =>
                           {
                               cmd("Hello");
                           }
                      );
        execute(f);

Upvotes: 1

Albin Sunnanbo
Albin Sunnanbo

Reputation: 47038

Like:

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

?

Upvotes: 0

Related Questions