【问题标题】:Access the value returned by a function in a finally block在 finally 块中访问函数返回的值
【发布时间】:2010-03-01 21:30:41
【问题描述】:

我想知道是否可以在 finally 块中获取函数的返回值。

我有一些这样的代码。

try
{
    return 1;
}
finally
{
    //Get the value 1
}

我知道可以通过添加一个可以保存返回值的变量来实现。但我想知道是否有可能以任何方式获得价值。

谢谢

【问题讨论】:

  • 使用变量。它将使您的代码更清晰、更易于维护、更易于理解。
  • 出于好奇,您为什么要这样做?我很想知道这将是理想解决方案的情况。
  • @Ian - 是的,我很少在 finally 块中做更多的清理工作,这仅适用于糟糕的 API。
  • 我使用 finally 块来跟踪信息。这里是调用的函数、传递的参数和结果代码。它用作分析器来验证性能。所以在 finally 块中,我执行 objectTrace.Save(ReturnValue),这就是为什么我想在没有额外变量的情况下访问该值。

标签: c# .net


【解决方案1】:

不,你不能那样做。

【讨论】:

  • Tomas Petricek 的答案是正确的——只需使用包装器
【解决方案2】:
int value = -1;

try 
{ 
    value = 1; 
} 
finally 
{ 

    // Now the value is available
} 

return value;

【讨论】:

  • 是的,我知道这是可能的。我只是想知道如果没有变量是否可能。
  • 这样就失去了早期回报的好处:-(
  • 提前返回?不确定你的意思@Vlad。这实际上就是编译器将把语句展开的内容。你是从视觉流的角度说的吗?
  • @David:至少那些认为早期回报是好事的人在这种情况下无法使用他们最喜欢的技术。
  • @Vlad:仍然可以提前返回。 (见我的回答)
【解决方案3】:

如果你想使用变量方法并提前返回,你可以这样做:

int Method()
{
    int @return = -1;
    try
    {
        @return = -2;
        return @return;
    }
    finally
    {
        // do something with @return
    }
}

【讨论】:

  • 或者更简洁:return @return = -2;
  • 我想问一下 - 变量名字体中的“@”是什么意思?
  • 对于 Jeffrey 的评论返回 @return = -2。那行得通吗?哪个先完成,最后还是返回
  • @pm100:它转义了关键字“return”(参见msdn.microsoft.com/en-us/library/aa664670%28VS.71%29.aspx)。 finally 将在 return 之后发生。
  • 做得很好。我没有在 IronPython/IronRuby 源代码中看到@转义接受,我没有意识到它在此之外经常使用。
【解决方案4】:

正如其他人已经提到的,在这种情况下您必须使用变量。但是,您可以使用 C# 3.0 lambda 函数将此行为模式包装到可重用的方法中:

static T TryFinally<T>(Func<T> body, Action<T> finallyHandler) { 
  T result = default(T);
  try {
    result = body();
  } finally {
    finallyHandler(result);
  }
  return result;
}

TryFinally 方法允许您编写您最初需要的内容,而无需重复该模式:

TryFinally(() => { 
    // body of the method
    return 1; 
  }, result => {
    // do whatever you need with 'result' here
  });

【讨论】:

    【解决方案5】:

    VB.Net 允许您这样做:

    Public Function GetValue() As Integer
        Try
            GetValue = 2
        Catch
            'Something happens
        Finally
            'Do something with GetValue
        End Try
    End Function
    

    这会告诉您一些关于 JIT 编译器将要做什么的信息。

    【讨论】:

    • 这似乎有点危险。在 finally 块中检查 GetValue 不会启动递归调用吗?
    • 我没怎么用过VB.Net,但是我觉得做递归函数调用需要括号,所以这样应该是安全的。
    • 这不是递归的。 GetValue(函数名)是 vb.net 中的一个可用变量。注意没有 Return 语句。当程序到达函数末尾时,返回 GetValue(在本例中为 2)。
    【解决方案6】:

    我认为实际的问题是 - 我可以系统地跟踪各种功能的退出(和进入?) - 大概是为了跟踪/故障排除等。aspect.net 怎么样。这使您可以将代码动态插入到事物中

    【讨论】:

    • 这不是真正的问题。我一直在寻找那部分,只是为了不必在返回值之前创建一个函数并设置它。跟踪只是项目的一小部分,可以看到每个功能所花费的时间(它是一个 web 服务,所以我们要确保性能仍然存在)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2010-09-08
    相关资源
    最近更新 更多