我目前正在开发一个项目,该项目分为几个部分,核心,UI等。在改变项目架构之前,我想知道处理异常的最佳方法是什么在核心库中?我的意思是,如何组织这些例外?例如,我可以使用有意义的消息抛出系统异常:
// Database implementation within Core library
class Database
{
void Foo()
{
// ...
if (Something())
throw new InvalidDataException(message:"The something!");
else
throw new InvalidDataException(message:"It's not something!");
}
}
class UI
{
void ShowDatabase()
{
var database = new Database();
try
{
database.Foo();
}
catch (InvalidDataException e)
{
CleanUp();
MessageBox.Show(e.ToString());
}
}
}
但核心库不必以任何方式处理用户。我对吗?好的,有另一种方式。我可以将带有错误代码的系统异常作为异常消息抛出,这样UI层就可以为用户自己选择警告消息:
static class ErrorCode
{
static string Something = "SomethingOccur";
static string NotSomething = "NotSomethingOccur";
}
class Database
{
void Foo()
{
// ...
if (Something())
throw new InvalidDataException(message:ErrorCode.Something);
else
throw new InvalidDataException(message:ErrorCode.NotSomething);
}
}
class UI
{
void ShowDatabase()
{
var database = new Database();
try
{
database.Foo();
}
catch (InvalidDataException e)
{
if (e.Message == ErrorCode.Something)
{
CleanUpSomthing();
MessageBox.Show(Resources.SomethingMessage);
}
else if (e.Message == ErrorCode.NotSomething)
{
CleanUpSomethingElse();
MessageBox.Show(Resources.NotSomethingMessage);
}
}
}
}
现在它更灵活,但我认为e.Message == ErrorCode.Something
看起来很丑陋。还有第三种方法,分别为任何案例实施例外:
class SomethingException : Exception
{
public SomethingException(string message = null, Exception inner = null) : base(message, inner) { }
}
class NotSomethingException : Exception
{
public NotSomethingException(string message = null, Exception inner = null) : base(message, inner) { }
}
class Database
{
void Foo()
{
// ...
if (Something())
throw new SomethingException()
else
throw new NotSomethingException();
}
}
class UI
{
void ShowDatabase()
{
var database = new Database();
try
{
database.Foo();
}
catch (SomethingException e)
{
CleanUpSomething();
MessageBox.Show(Resources.SomethingMessage);
}
catch (NotSomethingException e)
{
CleanUpSomethingElse();
MessageBox.Show(Resources.SomethingMessage);
}
}
}
它看起来更好,但每个案例在某个时刻会有数百个例外。听起来不错。
所以,问题是 - 处理核心库中的异常的最佳方法是什么?也许有最好的做法?
P.S。对不起我的英语,顺便说一句。
答案 0 :(得分:7)
一般做法应该是这样的:
在异常类型与特定情况匹配的任何情况下,您都可以使用标准.NET异常类(例如ArgumentNullException
,InvalidOperationException
)。有很多.NET异常类,你需要了解它们才能知道扔哪个以及何时抛出。
在严格连接到Core库逻辑的错误情况下,您可以定义自己的异常类,并使用它们进行抛出。
您应该创建一个异常层次结构,其中基本异常类表示一般错误,以及从它们继承的更具体的异常类。例如,您定义的基本异常类可能被命名为:ex。 CalculationExcepion
。然后定义从中继承的类 - 指定特定类型的计算异常。使用这种方法,您的库的用户将能够捕获基本异常(以涵盖许多错误情况),或根据他们的偏好处理特定异常。
您可以在异常中引入其他属性,但要注意ErrorCode
之类的属性,最终不得使用一个可能有50个不同错误代码的通用异常类 - 这将难以处理对于您的Core库的用户。您可以在特定错误类型的有限数量的特殊情况下使用ErrorCode
这样的属性,例如在执行GET请求时获得的HTTP代码:200,500,404和其他一些代码 - 但数量有限。
应该记录核心库中的公共方法和属性,了解它们抛出的异常类型以及何时可以预期这些异常。