错误处理(Operation Result)方法
自己开发的公众号,可以领取淘宝内部优惠券

问题
现在有一个FileStorageService类,继承自IStorageService,具体实现如下
public interface IStorageService
{
void WriteAllBytes(string path, byte[] buffer);
byte[] ReadAllBytes(string path);
} public class FileStorageService : IStorageService
{
public void WriteAllBytes(string path, byte[] buffer) {
File.WriteAllBytes(path, buffer);
} public byte[] ReadAllBytes(string path)
{
return File.ReadAllBytes(path);
}
}
假设调用其中任一一个方法出现异常,例如读写文件时候经常碰见的异常:IOException, DirectoryNotFoundException, FileNotFoundException,UnauthorizedAccessException… 甚至是 OutOfMemoryException
方案1-不是我的问题
IStorageService 不关心抛出的异常,那是使用者的职责。如此便将问题抛给了使用IStorageService接口的用户,它们必须要捕获有可能抛出的异常,往往一种偷懒的做法就是使用try catch语句将其包裹起来,如:
IStorageService myStorageService = Resolver.Resolve<IStorageService>();
try
{
myStorageService.ReadAllBytes("C:\stuff.data");
} catch (Exception exception)
{
// please don't write generic error messages like this, be specific
Logger.Log("Oops something went wrong: " + exception.Message);
}
catch exception并不是什么好主意,而且每次调用都需要使用try catch很不方便
方案2-创建新的异常类
一种改进的方法就是创建我们自己的异常类如StorageReadException,不管以后具体的实现如何变化,我们仅捕获特定的异常来进行异常处理
public class StorageReadException : Exception
{
public StorageReadException(Exception innerException)
: base(innerException.Message, innerException)
{
}
}
之前的FileStorageService实现更改为:
public byte[] ReadAllBytes(string path)
{
try
{
return File.ReadAllBytes(path);
}
catch (FileNotFoundException fileNotFoundException)
{
throw new StorageReadException(fileNotFoundException);
}
}
调用代码:
IStorageService myStorageService = Resolver.Resolve<IStorageService>();
try
{
myStorageService.ReadAllBytes(path);
}
catch (StorageReadException sre)
{
Logger.Log(String.Format("Failed to read file from path, {0}: {1}", path, sre.Message));
}
同样存在try catch 包裹问题,而且用户必须依赖一个新的异常类型
方案3-Try 模式并返回一个Complex Result
我们可以使用Try模式来避免用户使用try catch,Try模式类似C#里int方法
bool TryParse(string s, out int result),我们对接口进行更改
byte[] ReadAllBytes(string path)
变为
bool TryReadAllBytes(string path, out byte[] result)
但是这样不能提供用户更多的错误信息。如果我们想要显示更多的有帮助的异常信息给用户,可以返回一个通用的结果类OperationResult<TResult>
public class OperationResult<TResult>
{
private OperationResult ()
{
} public bool Success { get; private set; }
public TResult Result { get; private set; }
public string NonSuccessMessage { get; private set; }
public Exception Exception { get; private set; } public static OperationResult<TResult> CreateSuccessResult(TResult result)
{
return new OperationResult<TResult> { Success = true, Result = result};
} public static OperationResult<TResult> CreateFailure(string nonSuccessMessage)
{
return new OperationResult<TResult> { Success = false, NonSuccessMessage = nonSuccessMessage};
} public static OperationResult<TResult> CreateFailure(Exception ex)
{
return new OperationResult<TResult>
{
Success = false,
NonSuccessMessage = String.Format("{0}{1}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace),
Exception = ex
};
}
}
FileStorageService的ReadAllBytes 方法变为
public OperationResult<byte[]> TryReadAllBytes(string path)
{
try
{
var bytes = File.ReadAllBytes(path);
return OperationResult<byte[]>.CreateSuccessResult(bytes);
}
catch (FileNotFoundException fileNotFoundException)
{
return OperationResult<byte[]>.CreateFailure(fileNotFoundException);
}
}
调用代码:
var result = myStorageService.TryReadAllBytes(path);
if(result.Success)
{
// do something
}
else
{
Logger.Log(String.Format("Failed to read file from path, {0}: {1}", path, result.NonSuccessMessage));
}
原文:Error Handling in SOLID C# .NET – The Operation Result Approach
错误处理(Operation Result)方法的更多相关文章
- InnoDB: Operating system error number 87 in a file operation. 错误87的解决方法
InnoDB: Operating system error number 87 in a file operation. 错误87的解决方法 140628 8:10:48 [Note] Plugi ...
- coreseek常见错误原因及解决方法
coreseek常见错误原因及解决方法 Coreseek 中文全文检索引擎 Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和 ...
- android 真机调试出现错误 INSTALL_FAILED_INSUFFICIENT_STORAGE 的解决方法。
关于这个神奇的 内存不够错误的通常解决方法,网上大把,建议大家在尝试过了网上的方法后再来尝试下我的这种方法. 编译工具: android studio 测试真机:米 2 调试的时候出现:INSTALL ...
- 无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问。)” (Microsoft SQL Server,错误: 5120)的解决方法
无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问.)” (Microsoft SQL Server,错误: 5120)的解决方法 问题描述: 在附加数据库到sql server时,附 ...
- 错误:Unsupported major.minor version 51.0(jdk版本错误)的解决方法
错误:Unsupported major.minor version 51.0(jdk版本错误)的解决方法 java.lang.UnsupportedClassVersionError: org/ap ...
- 批处理命令篇--配置免安装mysql 5.6.22, 以及1067错误的一个解决方法
mysql 服务启动出现1067错误的一个解决方法: 当服务启动出现1067错误时,可查看“windows 事件查看器”,发现类似错误提示 Can't find messagefile 'F:\ ...
- IIS发布网站浏览之后看到的是文件目录 & Internal Server Error 处理程序“ExtensionlessUrlHandler-ISAPI-4.0_64bit”在其模块列表中有一个错误模块“IsapiModule” 解决方法 & App_global.asax.pduxejp_.dll”--“拒绝访问。 ”
Q:IIS发布网站浏览之后看到的是文件目录 A:它出现了一个说到.NET4.0 更高框架什么的错误,所以我将 .NTE CRL版本由4.0改为2.0了,改为2.0后就出现了只能浏览文件目录了.改为4. ...
- ORA-04091错误原因与解决方法
最近工作中写了一触发器报错:ORA-04091:table XX is mutating, trigger/function may not see it. 下面通过官方文档及网友提供资料分析一下错 ...
- Eclipse进度条出现“Remote System Explorer Operation”解决方法
Eclipse进度条出现“Remote System Explorer Operation”解决方法
随机推荐
- linux文件链接
我的github,欢迎关注,分享知识与技术 链接:一种在共享文件和访问它的用户的若干目录项之间建立联系的一种方法. Linux中包括两种链接:硬链接(HardLink)和软链接(Soft Link), ...
- EasyUi取消选中表格的所有行
- js判断页面从何种浏览器打开
问题 有时项目需要根据不同的设备进行不同的处理,需要判断到底是哪种设备打开了项目. 移动端浏览器检测 移动终端浏览器版本信息: var browser = { versions: function ( ...
- vtk-py z-Buffer可见算法
C++版例子: https://lorensen.github.io/VTKExamples/site/Cxx/PolyData/SelectVisiblePoints/ 优点: Simple to ...
- Sessions in BSU
Sessions in BSU 有n项考试.每项考试给定两个时间,你可以任意选择一个时间.每个时间点只能考一场考试,请问在最优情况下最早考完的时间.n<=1e6. 把题目抽象成图论模型:在每项考 ...
- c++编码规范(摘录)
在同一项目组应明确规定对接口函数参数的合法性检查应由函数的调用者负责还是由接口函数本身负责,缺省是由函数调用者负责. 函数的规模尽量限制在200行以内.说明:不包括注释和空格行. 一个函数仅完成一件功 ...
- opencv第一课,安装配置
下载工具:本教程以OpenCV3.2.0为例. 解压:本教程解压到D盘,解压的其它地方也是可以的,解压完后得到一个名为opencv目录. 配置系统变量:选择此电脑(计算机)->右键属性选择-&g ...
- mongoDB副本集+分片集群
首先搭建一个副本集(三台机器) 主,从,仲裁 然后搭建分片shard1,在每台机子上启用shard1(这里就写一个分片吧!!如果写多了怕初学者会混乱,先写一个.然后可以按照同样的方法写第二个,第三个) ...
- C语言预处理命令之文件包含
文件包含预处理命令的一般形式是: #include<文件名> 或者 #include“文件名” #include命令告诉预处理器用指定文件的内容替换这条命令,两种不同的命令格式决定了预处理 ...
- maven 中 指定jdk 和 编译编码,仓库位置
<!-- 配置编译选项 --> <profile> <id>jdk1.8</id> <activation> <activeByDef ...