如何在 C# 中将代码块(不是完整方法)作为参数传递
本文关键字:方法 参数传递 代码 | 更新日期: 2023-09-27 18:35:45
我正在csharp(.net 4.0)中构建一个消息传递应用程序,我的类具有发送/接收消息的基本方法:
void sendMessage( string msgBody, string properties);
object getNextMessage();
object getMessageById( string msgId);
这些方法中的每一种都依赖于底层连接;如果连接过时,我使用 try/catch 和一些重试逻辑进行额外的尝试,如下所示:
public object getNextMessage(){
object nextMessage = null;
int retryAttempts = 0;
int MAX_ATTEMPTS = 3;
while( retryAttempts < MAX_ATTEMPTS){
retryAttempts++;
try{
nextMessage = connection.getMessage("queueName");
}catch(Exception e){
}
}
return nextMessage;
}
由于重试逻辑是通用的,因此我希望避免在每个方法中重复相同的代码。我想创建一个通用的重试函数并执行以下操作:
public object makeAttempt( CodeBlock codeBlock){
while( retryAttempts < MAX_ATTEMPTS){
retryAttempts++;
try{
return codeBlock.invoke()
}catch(Exception e){
}
}
return null;
}
..我想使用这样的makeAttempt
,或类似的东西:
public object getNextMessage(){
makeAttempt() => {
return connection.getMessage("queueName");
}
}
我对此进行了审查,但它涉及将整个函数作为参数传递,我没有这样做。我还查看了.net Lambda表达式,但我没有看到连接。
我没有做太多 C#,所以请原谅 n00b 问题:-)
你快到了
- 你只需要将 lambda 表达式括在 ()
中,因为它是一个方法参数。还需要使用 makeAttempt
中的返回值来为 getNextMessage
方法提供返回值。所以:
public object getNextMessage(){
return makeAttempt(() => {
return connection.getMessage("queueName");
});
}
或者更简单地说,使用表达式 lambda:
public object getNextMessage(){
return makeAttempt(() => connection.getMessage("queueName"));
}
当然,这一切都是假设CodeBlock
是委托类型,例如
public delegate object CodeBlock();
还需要将makeAttempt
更改为调用Invoke
而不是invoke
- C# 区分大小写。我强烈建议您也遵循 .NET 命名约定,其中方法PascalCased
而不是camelCased
。
编辑:如评论中所述,您可以将其设为通用:
public T CallWithRetries<T>(Func<T> function)
{
for (int attempt = 1; attempt <= MaxAttempts; attempt++)
{
try
{
return function();
}
catch(Exception e)
{
// TODO: Logging
}
}
// TODO: Consider throwing AggregateException here
return default(T);
}