pen*_*ake 12 c# error-handling exception status
我想知道如何决定:
1)如果要抛出自定义异常或
2)返回一种LOG对象,其中包含'CityNotFound','ReferenceConstraintBroken'等标志.
我一直在阅读例外是昂贵的.如果我只需要知道过程结果的具体细节,对我而言,拥有一个仅包含过程的必要信息的自定义"过程LOG对象"听起来更有益.
所以,如果我回到我的问题:
什么时候更好地抛出一个异常,什么时候更好地返回一些错误日志'对象'?
bit*_*ise 16
抛出异常以提供更多信息(异常类型,消息等)以便正确处理并表示:
我实际上不鼓励返回"日志对象"(即返回一个异常对象,而不是抛出一个)
if
语句分析以检查结果并处理潜在的错误
out
参数),否则你不能"冒泡"错误/异常进行范围处理,从而导致进一步的限制如果你想返回"日志对象",你应该使用布尔返回值和有意义的方法(即FindCity
)或带有out
布尔参数的方法(即TryFindCity
).这样,您不需要指定标志,只需使用其布尔返回允许您确定将要标志值的方法.
编辑
根据OP的评论,如果有一个巨大的方法有许多可能的验证错误,那么应该重构巨大的方法来调用每个抛出适当异常的较小方法.然后,巨大的方法可以简单地重新抛出每个异常,或者只是允许每个异常冒泡,如果它不应该是处理它的那个异常.
如果存在阻止"正确分离"的验证依赖性,那么只需ValidationException
使用正确的参数抛出一个.下面是这个课程的一个例子:
public class ValidationException : Exception {
private readonly object _Field;
public object Field { get { return _Field; } }
public ValidationException(string message) : base(message) { }
public ValidationException(string message, object field)
: this(message) {
_Field = field;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以抛出一个解释验证错误的异常.
如果您担心异常的性能,可以考虑"测试人员"模式,在大多数情况下可以用它来避免它们(在我看来,它还使代码比try/catch更具可读性) .
// Traditional try catch
try
{
var record = myDb.myTable.Select(primaryKey);
// do something with record...
}
catch (RecordNotFoundException)
{
// The record not found in the database... what to do?
}
// Tester-doer pattern
if (myDb.myTable.RecordExists(primaryKey))
{
var record = myDb.myTable.Select(primaryKey);
// do something with record...
}
else
{
// The record not found in the database... what to do?
}
Run Code Online (Sandbox Code Playgroud)
同样的结果,没有例外.成本是你必须自己编写"RecordExists"函数,通常它就像做返回COUNT FROM myTable WHERE PrimaryKey = foo == 1这样简单.