使用自定义ErrorHandler类避免Try Catch Stements - C#

时间:2015-09-03 09:09:46

标签: c# .net error-handling

我有一个暴露某些功能的类, 我想确保异常将由自定义的ErrorHandler类处理。

目前我可以通过每个方法的try / catch语句实现这一点,并通过错误处理程序处理异常。

我的问题是,是否有更好的方式/设计模式来实现它。

代码:

public class BasicErrorHandler
{
    public void ProcessException(Exception ex)
    {
        //Does error handling stuff
    }
}

public class Manager
{
    BasicErrorHandler _errorHandler;

    public Manager()
    {
        _errorHandler = new BasicErrorHandler();
    }

    public void MethodA()
    {
        try
        {
            //Does Something    
        }
        catch(Exception ex)
        {
            _errorHandler.ProcessException(ex);
        }            
    }

    public void MethodB()
    {
        try
        {
            //Does Something Else
        }
        catch(Exception ex)
        {
            _errorHandler.ProcessException(ex);
        }
    }
}

5 个答案:

答案 0 :(得分:4)

DRY principles保持一致,您可以将container .hide() .find('input') .disable(); 逻辑包装到自己的方法中,该方法可以预测实际工作:

try...catch

答案 1 :(得分:3)

我已经快速制作了这个并没有考虑太多的影响,但是如果你想避免所有的try / catch块,你可以做类似的事情:

public class MultiFieldComparer : IEquatable<IEnumerable<object>>, IEqualityComparer<IEnumerable<object>>
{
    private IEnumerable<object> objects;

    public MultiFieldComparer(IEnumerable<object> objects)
    {
        this.objects = objects;
    }

    public bool Equals(IEnumerable<object> x, IEnumerable<object> y)
    {
        return x.SequenceEqual(y);
    }

    public int GetHashCode(IEnumerable<object> objects)
    {
        unchecked
        {
            int hash = 17;
            foreach (object obj in objects)
                hash = hash * 23 + (obj == null ? 0 : obj.GetHashCode());
            return hash;
        }
    }

    public override int GetHashCode()
    {
        return GetHashCode(this.objects);
    }

    public override bool Equals(object obj)
    {
        MultiFieldComparer other = obj as MultiFieldComparer;
        if (other == null) return false;
        return this.Equals(this.objects, other.objects);
    }

    public bool Equals(IEnumerable<object> other)
    {
        return this.Equals(this.objects, other);
    }
}

然后使用它:

public class BasicErrorHandler
{
    public void ProcessException(Exception ex)
    {
        //Does error handling stuff
    }

    public void Do(Action act)
    {
        try
        {
            act();
        }
        catch(Exception ex)
        {
            ProcessException(ex);
        }
    }
}

答案 2 :(得分:2)

设计模式可以解决问题。你想解决哪个问题? Try Catch块有什么问题?

我唯一想象的是你想拥有更干净的代码。一些答案提出了一个带有动作的辅助方法。给定封装委托的辅助方法:考虑使用这些委托对堆栈跟踪和调试会话的影响。它可能使记录等更难以理解。

如果你打算分离关注点,我会说如果你无法处理它,就不要抓住异常。让调用该方法的类处理它。如果你坚持在班上有一个处理程序,我会建议控制反转。这样,您的类无法控制确定哪个类应该处理其异常。

答案 3 :(得分:1)

Rx .net适合你。高级错误处理使您能够高度自定义错误处理。查看pages about that

例如:

var source = new Subject<int>();
var result = source.Catch<int, TimeoutException>(tx=>Observable.Return(-1));
result.Dump("Catch");
source.OnNext(1);
source.OnNext(2);
source.OnError(new ArgumentException("Fail!"));

您将获得以下输出:

Catch-->1
Catch-->2
Catch failed-->Fail!

重试次数,处理方法可以花费多少时间,一切都可以配置。

答案 4 :(得分:1)

以下是解决问题的面向方面的方法,这使用PostSharp进行编织。

[Serializable]
public class HandleExceptionsAttribute : OnExceptionAspect {
    /// <summary>
    /// Initializes a new instance of the <see cref="HandleExceptionsAttribute"/> class.
    /// </summary>
    public HandleExceptionsAttribute() {
        AspectPriority = 1;
    }

    public override void OnException(MethodExecutionArgs args) {
        //Suppress the current transaction to ensure exception is not rolled back
        using (var s = new TransactionScope(TransactionScopeOption.Suppress)) {
            //Log exception
            using (var exceptionLogContext = new ExceptionLogContext()) {
                exceptionLogContext.Set<ExceptionLogEntry>().Add(new ExceptionLogEntry(args.Exception));
                exceptionLogContext.SaveChanges();
            }
        }
    }
}

[HandleExceptions]
public class YourClass {

}