我应该在初始化器中创建异常对象还是在每个方法中编写异常对象?
本文关键字:异常 对象 方法 初始化 创建 我应该 | 更新日期: 2023-09-27 18:18:46
在我的Service类中,我创建了一个像这样的异常实例:
protected ServiceException _ex;
protected void Initialize()
{
_ex = new ServiceException();
}
在后面的这些类中,如果出现问题,我会调用这个异常:
public void Delete<T, V>(T item, V repo)
where T : Microsoft.WindowsAzure.StorageClient.TableServiceEntity
where V : IAzureTable<T>
{
try
{
repo.Delete(item);
}
catch (Exception ex)
{
_ex.Errors.Add("", "Error when deleting " + typeof(T).Name.ToLower());
throw _ex;
}
}
在此之外的控制器中,我检查异常:
catch (Exception e) { log(e); }
然后我处理这个:
protected void log(Exception ex)
{
if (ex is ServiceException)
{
ModelState.Merge(((ServiceException)ex).Errors);
}
else
{
Trace.Write(ex);
ModelState.AddModelError("", "Database access error: " + ex.Message);
}
}
抱歉的长例子,但我想知道的是,如果这是一个有效的事情,我正在做。特别是有人评论说,我每次都创建一个新的_ex值,即使没有例外。我这样做的原因是,每个控制器大约有二十个try-catch块,我认为最好在开始时创建一个_ex对象,这样就不必有二十个区域,如果出现问题,我可以创建一个新的_ex。如果有人能告诉我这一切是否合理,我会很感激。谢谢。
我建议在一个单独的结构中收集错误,然后在异常类构造器中传递它,而throw,这样你就不会创建异常类的实例,除非真的需要它:
// class constructor, List of strings or any entity like ErrorEntry
IList<string> errors = new List<string>();
// collect while execution
errors.Add(errorText);
// raise an exception
throw new ServiceException(this.errors);
顺便说一句,你能给一些例子,当你跟踪一个错误,但不引发异常?
异常并不是类持久化内部状态的一部分,它对类没有任何描述,也不能真正帮助类做它需要做的事情,它只是类执行其正常功能时可能发生的不良副作用。为此,它不需要处于类的持有状态。只需在需要时创建它。
至于你担心可能在20个不同的地方创建这个,也许这应该让你质疑为什么类有20个不同的事情要做。所有这些都是逻辑相关的吗?或者您的类实际上是许多类的集合,只是没有这样声明?
(也就是说,如果创建异常的方式在每种情况下都是通用的,那么您当然可以将创建重构为自己的可重用方法/类。)
我不会那样做的:
- 如果(当)你开始使用多个线程,这将变得非常丑陋,当两个异常发生在大约同一时间。
- 当两个异常依次发生时,您希望如何进行清理?是否每个处理异常的地方都需要自己进行清理?
- 如果一个人持有异常,并且在一个人有机会处理它之前,更多的信息被添加或替换到唯一的实例中,该怎么办?
类似的方法在Win32 API (SetLastError
)和一些运行时库(即C中的errno
)中使用。在我看来,它使错误处理变得困难。
建议——如果你想给调用者更多关于错误的信息——在操作过程中收集信息,并在新创建的异常中报告它。注意,"操作"可能意味着对服务的多次调用,但调用者仍将其视为单个操作。例如,OpenFile, WriteData, CloseFile可以由调用者单独操作,也可以将每个操作重新定义为单个调用。