我正在尝试将匿名委托(无输入参数,无返回值)的参数传递给函数。
像这样的东西:
private function DoSomething(delegate cmd)
{
cmd();
}
然后,我想使用此函数以这种方式调用函数:
DoSomething(delegate
{
Console.WriteLine("Hooah!");
});
我想要这种特定的方式,因为它很容易使用书写风格。
可能的?
正是出于这种目的,Microsoft在.NET框架中创建了Action和Func包装器类。这两个类都依赖于匿名函数。如果您不需要返回任何结果,只需执行匿名函数,请使用Action:
private void DoSomething(Action action)
{
action();
}
可以这样使用:
DoSomething(() =>
{
Console.WriteLine("test");
});
该() =>
术语是lambda表达式,表示类似的东西input with no parameters is calling ...
。请参阅文档以获取详细说明。
如果要返回结果,请使用Func委托:
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块中,并在发生情况时记录日志。这样我减少了重复代码:
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.");
});
您仍然可以使用原始的委托概念。Action和Func类只是预定义的通用委托方法的包装。
// 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");
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句