我目前正在从事一个项目,该项目分为核心、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);
}
}
}
它看起来更好,但在某个时刻每个案例都会有数百个异常。听起来很糟糕。
那么,问题是——在 Core 库中处理异常的最佳方法是什么?也许有任何最佳实践?
附言抱歉我的英语不好,顺便说一句。
最佳答案
一般的做法应该是这样的:
在异常类型与特定情况匹配的任何情况下,您都可以使用标准 .NET 异常类(例如
ArgumentNullException
、InvalidOperationException
)。有很多 .NET 异常类,您需要对它们有一些了解才能知道抛出哪一个以及何时抛出。在错误与核心库逻辑严格相关的情况下,您可以定义自己的异常类,并使用它们来抛出异常。
您可能应该创建一个异常层次结构,基本异常类代表一般错误,更具体的异常类继承自它们。例如,您定义的基异常类可能被命名为:ex。
计算异常
。然后定义从它继承的类 - 指定特定种类的计算异常。使用这种方法,您的库的用户将能够捕获基本异常(以涵盖许多错误情况),或处理特定异常 - 基于他们的偏好。您可以在您的异常中引入额外的属性,但要注意像
ErrorCode
这样的属性,不要以一个可能有 50 个不同错误代码的通用异常类结束 - 这将是核心库的用户很难处理。您可以在特定错误类型的有限数量的特殊情况下使用诸如ErrorCode
之类的属性,例如您在执行 GET 请求时获得的 HTTP 代码:200、500、404 和其他一些代码 - 但数量仍然有限。应记录核心库中的公共(public)方法和属性,说明它们抛出的异常类型以及何时可以预期这些异常。
关于c# - 核心库的异常架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27703628/