核心库的异常体系结构
本文关键字:体系结构 异常 核心 | 更新日期: 2023-09-27 18:35:36
我目前正在做一个分为几个部分的项目,核心,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);
}
}
}
它看起来更好,但在某个时刻每种情况都会有数百个例外。听起来很糟糕。
所以,问题是 - 处理核心库中异常的最佳方法是什么?也许有任何最佳实践?
附言对不起我的英语,顺便说一句。
一般做法应该是这样的:
-
可以使用标准 .NET 异常类(例如
ArgumentNullException
,InvalidOperationException
) 在异常类型与特定情况匹配的任何情况下。有很多 .NET 异常类,您需要了解它们才能知道要抛出哪个类以及何时抛出。 -
在与 Core 库的逻辑严格相关的错误的情况下,您可以定义自己的异常类,并使用它们来抛出。
-
您可能应该创建一个异常层次结构,其中基本异常类表示一般错误,更具体的异常类继承自它们。例如,您定义的基异常类可能命名为:ex。
CalculationExcepion
.然后定义从它继承的类 - 指定特定类型的计算异常。使用这种方法,库的用户将能够捕获基本异常(以涵盖许多错误情况),或根据他们的偏好处理特定异常。 -
您可以在异常中引入其他属性,但要小心使用诸如
ErrorCode
这样的属性,以免最终得到一个可能具有 50 个不同错误代码的通用异常类 - 这对于 Core 库的用户来说很难处理。您可以在特定错误类型的有限数量的特殊情况下使用此类属性ErrorCode
,例如执行 GET 请求时获得的 HTTP 代码:200、500、404 和其他一些代码 - 但数量仍然有限。 -
应记录 Core 库中的公共方法和属性,说明它们引发的异常类型以及何时会出现这些异常。