0

是否可以获得有关方法返回位置的运行时信息?

我的意思是,如果该方法在运行其所有代码行之后返回,或者由于某些条件而发生了较早的 return 语句。

该场景使用拦截器来创建应该存在于方法范围内的 UnitOfWork。例如,让我们考虑以下代码:

[UnitOfWork]
public void Foo()
{
    // insert some values to the database, using repositories interfaces...
    DoSomeChangesInTheDataBaseUsingRepositories();
    var result = DoSomethingElse();
    if (!result) return;

    DoMoreLogicBecuseTheResultWasTrue();            
}

我有一个拦截器类,它为用 [UnitOfWork] 标记的方法打开线程静态工作单元,当方法的范围结束时,它在 UoW 上运行提交并处理它。

这很好,但让我们考虑上面的场景,由于某种原因,程序员决定在方法的中间返回,并且在这种情况下,存储库所做的更改不应该被持久化。

我知道这可能表明方法设计错误,但请注意,这可能是由程序员编写的场景,我想保护我的数据库免受此类场景的影响。

另外,我不想在方法本身中添加代码来告诉我它在哪里结束。我想通过方法 info 以某种方式推断它的返回点,如果它不在其范围的末尾,拦截器将知道不提交。

4

4 回答 4

3

简单的答案是使用BREAKPOINTS和调试。

编辑:- 正如梅尔斯在评论中提到的那样。这可能是一个有用的建议。

如果您的应用程序对时间非常敏感,请设置条件断点,这样它们就不会真正停止执行流程。他们确实会跟踪 Hit Count,您可以使用它来回溯执行流程。

只是为了你的注意。从微软网站: -

对于那些有调试本机 C++ 或 VB6 代码经验的人,您可能已经使用了在“自动”窗口中为您提供函数返回值的功能。不幸的是,托管代码不存在此功能。虽然您可以通过将返回值分配给局部变量来解决此问题,但这并不方便,因为它需要修改您的代码。在托管代码中,确定您已跨过的函数的返回值要复杂得多。我们意识到我们无法在这里始终如一地做正确的事情,因此我们删除了该功能,而不是在调试器中为您提供不正确的结果。但是,我们希望为您带来这一点,我们的 CLR 和调试器团队正在寻找一些潜在的解决方案来解决这个问题。

于 2013-08-16T06:44:14.057 回答
1

有几种方法通常表明方法由于某种原因提前退出,一种是使用实际返回值,如果该值是有效结果,那么您的方法可能正确完成,如果它的另一个值可能不是,这个是大多数TryXXX方法遵循的模式

int i;
//returns false as wasn't able to complete
bool passed = int.TryParse("woo", out i); 

另一种是捕获/处理异常,如果发现异常,则该方法未按预期完成

try
{
Method();
}
catch(Exception e)
{
//Something went wrong (e.StackTrace)
}

注意:捕获Exception是个坏主意,应该捕获正确的异常,即NullReferenceException

编辑:

在回答您的更新时,如果您的代码依赖于您的方法的成功,您应该将返回类型更改为布尔值,否则,如果不成功则返回 false

于 2013-08-16T06:53:02.903 回答
0

通常,如果您无法调试它,您应该使用跟踪日志来观察您的代码流。

于 2013-08-16T06:45:02.243 回答
0

你总是可以做这样的事情:

private Tuple<int, MyClass> MyMethod()
{
    if (condition)
    {
        return new Tuple<int, MyClass>(0,new MyClass());
    }
    else if(condition)
    {
        return new Tuple<int, MyClass>(1, new MyClass());
    }

    return new Tuple<int, MyClass>(2,new MyClass());
}

这样,您将获得返回 MyClass 对象的索引。一切都取决于您要完成的工作以及原因-充其量尚不清楚。正如其他人提到的 - 这就是返回值的用途。

我很想知道你想做什么......

于 2013-08-16T06:52:16.480 回答