我想知道我是否在我的代码中正确处理异常,所以希望有人会对我的代码给我一些想法
public IEnumerable<Job> GetAll() {
try {
return this._context.Jobs;
} catch (SqlException ex) {
//error so dispose of context
this.Dispose();
//wrap and rethrow back to caller
throw new CentralRepositoryException("Error getting all jobs", ex);
}
}
此方法是我的业务逻辑的一部分,并调用上面的方法
public IEnumerable<Job> GetAllJobs() {
try {
return this._jobsRepository.GetAll();
} catch (CentralRepositoryException ex) {
//logging code to go here
//throw back to caller
throw;
} catch (Exception ex) {
this._jobsRepository.Dispose();
//logging code to go here
//throw simple exception to caller
throw new CentralRepositoryException("A general exception has occurred");
}
}
我的自定义异常
public class CentralRepositoryException : System.Exception {
public CentralRepositoryException(string message, Exception innerException)
: base(message, innerException) {
}
public CentralRepositoryException(string message){
}
}
答案 0 :(得分:2)
这种方法存在一些问题:
IEnumerable<T>
将导致代码延迟执行。即使您返回IEnumerable<T>
,也请在代码中使用this._jobsRepository.GetAll().ToList();
IDisposable
块中的所有using
个对象换行所以另一种选择是:
public IEnumerable<Job> GetAllJobs() {
try {
using(var jobsRepository = new JobsRepository()) // !!! Use Dependency Injection, etc
{
return jobsRepository .GetAll().ToList(); // !! NOTE: ToList() avoids delayed execution
}
} catch (CentralRepositoryException ex) {
//logging code to go here
//throw back to caller
throw;
} catch (Exception ex) {
//logging code to go here
//throw simple exception to caller
throw new CentralRepositoryException("A general exception has occurred", ex); // !!!!!! INCLUDE THE ORIGINAL ERROR !!!!!!!
}
}
答案 1 :(得分:0)
在松散堆栈跟踪时,不应该简单地重新抛出异常。我可以看到你正在使用它们处理对象,这应该在finally block中。
除非你真正处理异常,否则你不应该使用catch,因为你希望它冒泡调用堆栈以便它可以修复 - 而不是隐藏。
答案 2 :(得分:0)
这不是Dispose()的正确用法。如果你发现你最终写了:
this.Dispose();
this._jobsRepository.Dispose();
这两个都是指同一个对象。为确保您只处理一次,该类的可重复性是声明IDisposable调用dispose。
这意味着如果您创建局部变量,则在using语句中执行此操作:
using(SomethingDisposable foo = new SomethingDisposable())
{
//...
}
或明确处置:
SomethingDisposable foo = new SomethingDisposable();
try
{
//...
}
finally
{
((IDisposable)foo).Dispose();
}
如果您创建了一个字段,那么您的课程也是一次性的:
class MyDisposable : IDisposable
{
private SomethingDisposable foo = new SomethingDisposable();
void IDisposable.Dispose()
{
foo.Dispose();
}
}
如果您以这种方式对待IDisposables,那么您的异常处理将不会与您的处置相混淆。