c# - 匿名委托(delegate)作为函数参数

标签 c# anonymous-delegates

我正在尝试将匿名委托(delegate)(无输入参数,无返回值)的参数传递给函数。

像这样:

private function DoSomething(delegate cmd)
{
     cmd();
}

然后,我想用这个函数来调用函数:

DoSomething(delegate
{
     Console.WriteLine("Hooah!");
});

我想要这种特定的方式,因为它易于使用的写作风格。

可能吗?

最佳答案

正是出于此类目的,Microsoft 创建了 ActionFunc .NET 框架中的包装器类。这两个类都依赖于 anonymous functions .如果不需要返回任何结果,只执行匿名函数,则使用 Action:

private void DoSomething(Action action)
{
    action();
}

可以这样使用:

DoSomething(() => 
{
    Console.WriteLine("test");
});

() => 项是一个 lambda expression并且意味着类似于 没有参数的输入正在调用 ...。有关详细说明,请参阅文档。

如果要返回结果,则使用 Func 委托(delegate):

private T DoSomething<T>(Func<T> actionWithResult)
{
    return actionWithResult();
}

用法:

Console.WriteLine(DoSomething<int>(() => 
{
    return 100;
}));

两个包装器都有接受最多 8 个参数的覆盖。

使用 Func 时,最后一个参数始终是返回类型:

// returns a string
Func<string> t = () => { return "test string"; };
// first parameter is of type int, result of type string
Func<int, string> toString = (id) => { return id.ToString(); };
// parameters are of type int and float, result is string
Func<int, float, string> sumToString = (n1, n2) => { return (n1 + n2).ToString(); };

Func 包装器可以直接与类型化参数一起使用:

Func<string, string> up = text => text.ToUpper();
Console.WriteLine(up("test"));

我经常使用 Func 来创建一个通用的执行器,它被包装在一个 try/catch block 中,并在发生某些事情时进行记录。这样我就减少了重复代码:

private T safeCallWithLog<T>(Func<T> action)
{
    try
    {           
        return action();
    }
    catch (Exception ex)
    {
        Console.WriteLine(String.Format("Oops ...: {0}", ex.Message));
    }
    // return default type if an error occured
    return default(T);
}

用法:

var result = safeCallWithLog<DbEntry>(() =>
            {
                return databaseContext.GetEntryWithId(42);
            });

var id = safeCallWithLog<int>(() =>
                    {
                        return databaseContext.GetIdFor("J.D.");
                    }); 

您仍然可以使用原来的 delegate concept . Action 和 Func 类只是 predefined generic delegate methods 的包装器.

// declare delegate contract
private delegate void output();
// create caller method
private void method(output fun)
{
    fun();
}
// some test functions, that must match exactly the delegate description
// return type and number of arguments
private void test1()
{
    Console.WriteLine("1");
}

private void test2()
{
    Console.WriteLine(DateTime.Now.ToString());
}

// call different methods
method(test1);
method(test2);
// inline call without hard coded method
method(delegate() 
{
    Console.WriteLine("inline");
});

关于c# - 匿名委托(delegate)作为函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21795819/

相关文章:

c# - Linq to XML 从 twitter API 解析单个 "status"节点

c# - 数据绑定(bind)到 xaml 中对象列表中的对象列表中的对象列表

c# - 这种类型的委托(delegate)叫什么(C#)

c# - 泛型传递类型成员以对泛型集合进行操作

c# - NCalc 在 vb.net 中创建自定义函数

c# - Selenium 3.8.0 wait.until 调用抛出异常

c# - win2D uwp 不会在 inkcanvas 中保存高亮笔画

c# - Dispatcher.Invoke with anonymous delegate 在 Silverlight 中有效但在 WPF 中无效

c# - 使用LINQ根据Where过滤List中的某个值