【问题标题】:C# Exception ListenerC# 异常监听器
【发布时间】:2017-07-17 17:27:01
【问题描述】:

C# 问题。任意类Class 有方法Foo(),一个可以抛出异常的方法。有没有办法给Class添加一个私有回调机制bar(),这样如果Foo()抛出一个异常,bar()将被触发执行之前抛出继续向上链?如果做不到,那么在异常被捕获之后呢?

-- 编辑--

由于最初的一些 cmets 是“这令人困惑,你在做什么,伙计”,我将进一步解决这个问题。

我想要一个异常监听器的原因是因为我有一些关于类 Class 的公开可读的布尔状态,我希望在抛出异常时将其设置为 true。由于Class 中可能存在多个引发异常的函数,因此我不想在每次引发异常时都将 hasError 设置为 true 的样板工作。自动化,宝贝。

所以我们的界面和主要功能是:

public interface IObjectProvider
{
    IEnumerable<object> Allobjects { get; }
}

public interface IContext
{
    delegate bool ContextIsStillValid(object o);
    delegate void Run(object o);
}

// main program
public static void Main() {
    IContext context = initcontext(...);
    IObjectProvider objectProvider = initobjectprovider(...);

    // ...program executes for awhile...

    foreach(var obj in objectProvider.AllObjects)
    {
        if(context.ContextIsStillValid(obj))
        {
            try
            {
                context.Run(obj);
            }
            catch(Exception e)
            {
                // log the error
            }
        }
    }
}

在上面的代码 sn-p 中,我们指定了一些 IContext 将使用一些 object 来“运行”,当且仅当IContext 首先成功通过了“验证”检查使用相同的object。美好的。现在,IContext 的常见实现变体如下(相信我的话,确实如此):

public class Class : IContext {

    private bool _hasError = false;

    // so our validation check is implemented with an internal flag. 
    // how is it set?
    public bool ContextIsStillValid = (o) => !_hasError;

    public void Run = 
    (o) =>
    {
        string potentially_null_string = getstring(...);
        if(potentially_null_string == null) 
        { 
            // our internal flag is set upon the need to throw an exception
            this._hasError = true; 
            throw new Exception("string was null at wrong time"); 
        }

        Global.DoSomethingWith(potentially_null_string.Split(',');
    };
}

在这里,我们演示了IContext 的常见实现,这样一旦Run 方法抛出一个ExceptionRun 方法就会变得不可访问,因为IsContextStillValid 随后总是返回false。

现在想象在我们的Run(object) 实现中还有其他抛出异常的调用。问题是每次我们想抛出一个新的异常,我们都必须复制代码到_hasError = true; throw new Exception(...);的效果。理想情况下,异常监听器会为我们解决这个问题,我很好奇你们中是否有人知道如何实现。

希望对您有所帮助。

【问题讨论】:

  • 你到底想做什么?你不能只使用try catch 和rethrow 吗?似乎是一个奇怪的问题......
  • 为什么不在Foo() 中放置一个try/catch,它会在catch 块中调用bar(),然后重新抛出?
  • 从技术上讲,您可以在 catch 块上使用异常过滤器来在调用堆栈展开之前观察异常。有关示例,请参阅exception filters 上的 SO 文档。
  • 我这样做的原因是因为我有一些关于类 Class 的布尔状态,我希望在抛出异常时将其设置为 true,基本上是一些 hasError 状态。由于Class 中可能存在多个引发异常的函数,因此我不想在每次引发异常时都将 hasError 设置为 true 的样板工作。自动化,宝贝。
  • @David 因为Foo() 内会有多个调用,这可能会导致错误,如果开发人员负责添加样板代码来驱动内部每次添加新更新时的状态。 @mike z 谢谢,我会调查的。 @gilmishal 请看我的编辑,谢谢。

标签: c# exception-handling callback


【解决方案1】:
public class MyClass
{
    public void Foo()
    {
        try
        {
            //Execute some code that might fail
        }
        catch
        {
            bar();
            throw;
        }
    }
    private void bar()
    {
        //do something before throwing
    }
}

【讨论】:

  • 我想补充一点,还需要考虑一个事实,即 bar() 本身的执行可能会引发错误。
  • 没错,这完全取决于您在做什么以及您希望它如何表现。
  • @CavanPage 感谢 Cavan,这个建议已经提出,这个建议可能有效,感谢您的意见。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 2011-07-09
相关资源
最近更新 更多