.NET Standard 2.0中C#方法返回多错误类型的优化方案咨询
推荐使用自定义结果类方案
在.NET Standard 2.0环境下,自定义一个包含数据、错误类型和错误信息的结果类,是解决这类需求的最优方案——它既能清晰返回有效数据,又能精准传递错误细节,比Try模式、输出参数或单一ErrorCode更灵活可控。
步骤1:定义错误类型枚举
先把需要区分的错误类型枚举出来,方便后续精准判断:
public enum ItemFetchErrorType { None, ConnectionFailed, // 连接外部数据源失败 InvalidItemsFound // 存在无效Item }
步骤2:定义泛型结果类
这个类可以复用在其他类似场景,同时承载数据、错误类型和错误细节:
public class OperationResult<T> { // 成功获取的有效数据(保证至少为空列表) public T Data { get; set; } // 快速判断是否发生错误 public bool HasError => ErrorType != ItemFetchErrorType.None; // 具体错误类型 public ItemFetchErrorType ErrorType { get; set; } // 错误描述信息 public string ErrorMessage { get; set; } // 可选:存储多个无效Item的具体详情(比如ID、无效原因) public List<string> InvalidItemDetails { get; set; } = new List<string>(); }
步骤3:改造GetAllItems方法
修改原方法返回自定义结果类,在内部处理异常和无效Item检查:
/// <summary> /// 获取所有有效Item,同时返回错误状态和详情 /// </summary> /// <returns>包含有效Item和错误信息的结果对象</returns> public OperationResult<List<Item>> GetAllItems() { var result = new OperationResult<List<Item>> { Data = new List<Item>() }; try { // 调用外部数据源获取原始数据 var rawItems = FetchFromExternalSource(); // 过滤有效Item,收集无效项信息 foreach (var item in rawItems) { if (IsItemValid(item)) { result.Data.Add(item); } else { result.ErrorType = ItemFetchErrorType.InvalidItemsFound; result.InvalidItemDetails.Add($"无效Item ID:{item.Id},校验失败原因:xxx"); } } // 补充无效项的汇总提示 if (result.InvalidItemDetails.Any()) { result.ErrorMessage = $"共发现{result.InvalidItemDetails.Count}个无效Item"; } } catch (Exception ex) { // 捕获连接失败或数据源异常 result.ErrorType = ItemFetchErrorType.ConnectionFailed; result.ErrorMessage = $"连接外部数据源失败:{ex.Message}"; } return result; } // 以下为示例辅助方法,根据实际业务实现 private List<Item> FetchFromExternalSource() { // 实际调用外部数据源的逻辑 throw new NotImplementedException(); } private bool IsItemValid(Item item) { // 实际的Item有效性校验逻辑 return item != null && !string.IsNullOrEmpty(item.Id); }
调用方使用示例
调用方可以清晰地分场景处理,代码可读性和可维护性更强:
var fetchResult = GetAllItems(); // 先处理有效数据 ProcessValidItems(fetchResult.Data); // 再根据错误类型做针对性处理 if (fetchResult.HasError) { switch (fetchResult.ErrorType) { case ItemFetchErrorType.ConnectionFailed: LogError(fetchResult.ErrorMessage); ShowConnectionFailedAlert(); break; case ItemFetchErrorType.InvalidItemsFound: LogWarning(fetchResult.ErrorMessage); foreach (var detail in fetchResult.InvalidItemDetails) { LogWarning(detail); } ShowInvalidItemsWarning(); break; } }
方案优势
- 对比Try模式:无需依赖输出参数,结果结构更清晰,能同时传递多种错误信息(不止是成功/失败)
- 对比单一ErrorCode:错误类型枚举更直观,还能附加错误详情、无效项列表等额外信息
- 对比输出错误消息:结构化的错误类型避免了字符串解析的麻烦,方便调用方做分支处理
- 泛型设计可复用在其他业务方法上,减少重复代码
内容的提问来源于stack exchange,提问作者0lli.rocks
相关产品推荐
相关产品推荐

