C#中如何通过泛型统一逻辑相似的错误响应处理重复方法
问题描述
开发过程中实现了5个执行逻辑完全相同的错误响应处理方法,代码如下:
private async Task<CheckResponse> ManageCheckResponseError(string code) { await LogErrorResponseAsync(new { StatusCode = code }); return CheckResponse.GetError(code.ToString()); } private async Task<BalanceResponse> ManageBalanceResponseError(string code) { await LogErrorResponseAsync(new { StatusCode = code }); return BalanceResponse.GetError(code.ToString()); } private async Task<DebitResponse> ManageDebitResponseError(string code) { await LogErrorResponseAsync(new { StatusCode = code }); return DebitResponse.GetError(code.ToString()); } private async Task<CreditResponse> ManageCreditResponseError(string code) { await LogErrorResponseAsync(new { StatusCode = code }); return CreditResponse.GetError(code.ToString()); } private async Task<CancelResponse> ManageCancelResponseError(string code) { await LogErrorResponseAsync(new { StatusCode = code }); return CancelResponse.GetError(code.ToString()); }
上述方法对应的所有响应类结构逻辑一致,均实现ICommonResponseOperations<T>接口,包含ErrorModel属性与静态GetError方法,仅类的自定义属性存在差异,类结构示例如下:
public class SampleResponse : ICommonResponseOperations<SampleResponse> { // 自定义业务属性 public string Entry { get; set; } public string EntryEmbedded { get; set; } // 错误处理相关属性 public ErrorModel ErrorModel { get; set; } public static SampleResponse GetError(string code) { return new SampleResponse { Entry = "", EntryEmbedded = "", ErrorModel = ErrorModel.GetError(code) }; } }
需求是通过C#泛型特性封装重复逻辑,简化代码实现。
解决方案
完全可以通过泛型实现逻辑复用,根据使用的C#版本可以选两种实现方案:
方案1:C# 11及以上版本(推荐)
利用C# 11新增的静态抽象接口成员能力,直接在接口层面约定GetError静态方法,无需额外传参。
- 调整泛型接口定义,增加静态抽象方法约束:
所有响应类的实现无需额外修改,只要保证public interface ICommonResponseOperations<T> where T : ICommonResponseOperations<T> { ErrorModel ErrorModel { get; set; } static abstract T GetError(string code); }GetError方法的返回值是当前响应类本身即可(注意修正示例中返回LoginResponse的笔误)。 - 封装唯一的通用错误处理方法,替换原来的5个重复方法:
private async Task<T> ManageResponseError<T>(string code) where T : ICommonResponseOperations<T> { await LogErrorResponseAsync(new { StatusCode = code }); return T.GetError(code.ToString()); } - 调用时直接指定响应类型即可,逻辑和原实现完全一致:
// 替换原ManageCheckResponseError调用 var checkError = await ManageResponseError<CheckResponse>(code); // 替换原ManageBalanceResponseError调用 var balanceError = await ManageResponseError<BalanceResponse>(code);
方案2:兼容C# 10及以下版本
低版本C#不支持静态抽象接口成员,可以通过传入错误对象工厂委托的方式消除重复逻辑:
- 定义通用错误处理方法:
private async Task<T> ManageResponseError<T>(string code, Func<string, T> errorFactory) { await LogErrorResponseAsync(new { StatusCode = code }); return errorFactory(code.ToString()); } - 调用时直接传入对应响应类的
GetError方法作为委托参数即可:var checkError = await ManageResponseError(code, CheckResponse.GetError); var balanceError = await ManageResponseError(code, BalanceResponse.GetError);
内容的提问来源于stack exchange,提问作者Simone Spagna
相关产品推荐
相关产品推荐

