编写代码时会不可避免的遇到“可能性错误”的处理,如
var x = Get(y);当Get方法有异常的情况就会传导到主函数上
一般来说,传统的处理是try…catch…
try
{
var x = Get(y);
}
catch(Exception ex)
{
...处理ex
}
但这样明显更为冗长,而且对于确定的错误类型无法显式编程
以下是一些流行的处理(从上至下适合越不需要错误处理的状况)
自定义Result Pattern
错误类型丰富,具有返回错误
class Result<T>
{
bool IsSuccess { get; }
T Value { get; }
string ErrorMessage { get; }
Result(bool isSuccess, T value, string errorMessage)
{
IsSuccess = isSuccess;
Value = value;
ErrorMessage = errorMessage;
}
static Result<T> Success(T value) => new Result<T>(true, value, null);
static Result<T> Fail(string errorMessage) => new Result<T>(false, null, errorMessage);
}
Result<Tx> GetResult(Ty y)
{
try
{
var x = Get(y);
Return Success<Tx>.Success(x);
}
catch(Exception1 ex)
{
Return Result<Tx>.Fail(ex.errorMessage);
}
}
Result<Tx> result = GetResult(y);
if(result.IsSuccess)
{
...
}
TryGet()方法样式
不在主函数上动手而是把错误处理移到执行函数上
bool TryGet(Ty y, out Tx result)
{
try
{
res = Get(y);
return true;
}
catch(Exception ex)
{
logger.Error(ex.Message);
}
return false
}
if(TryGet(y,out x))
{
...
}元祖模式匹配
简单,不需要out,扩展性可以将bool换成更丰富的类型(Result或性能更好的Enum)
(bool isSuccess, Tx value) EvalGet(Ty y)
{
try
{
return (true, Get(y))
}
catch(Exception ex)
{
logger.Error(ex.Message);
}
return (true, default(Tx))
}
if(EvalGet(y) is (true, var x))
{
...
}
OneOf匹配
联合类型,多样化处理,最好的方案
enum ResultError
{
Exception,
Others
}
OneOf<Tx value,ResultError> TryGet(Ty y)
{
try
{
return Get(y);
}
catch()
{
return ResultError.Exception
}
return ResultError.Others
}
var result = TryGet(y).Match(
value => return value
error => return error.ToString()
)
TryGet(y).Switch(
value => {
...
}
)