如何实现子类向父类传递参数不同但返回值统一的回调委托?
解决方案
首先修正核心问题:你的原代码存在两个关键问题——父类委托签名设计冗余,且子类错误地直接赋值了API调用的结果(而非委托本身)。以下是优化后的实现方案:
1. 调整父类的委托定义
将父类的委托简化为只接收CancellationToken、返回统一类型的签名,因为子类的参数可以通过闭包绑定,不需要父类感知:
public class BaseDownloadService { public ServerAPI? Api = InitApiService(); // 简化委托签名:仅接收取消令牌,返回统一的ReportFileModel任务 public Func<CancellationToken, Task<ReportFileModel>> DownloadFileDelegate { get; set; } = default!; public async Task ExecuteDownloadFile() { if (DownloadFileDelegate == null) throw new InvalidOperationException("下载委托未初始化"); var reportFile = await DownloadFileDelegate(_cancellationTS.Token); // 通用文件处理逻辑(比如保存、解析等) } }
2. 子类绑定委托与参数
在子类构造函数中,通过lambda表达式将API方法与子类的特定参数绑定,生成符合父类委托签名的实例:
Class1(带EmployeeId和MonthPeriod参数)
public class ExcelDownloadService : BaseDownloadService { private readonly int _employeeId; private readonly string _monthPeriod; public ExcelDownloadService(int employeeId, string monthPeriod) { _employeeId = employeeId; _monthPeriod = monthPeriod; // 通过lambda捕获子类参数,适配父类委托签名 DownloadFileDelegate = async (token) => await Api.GetMyExcelFile(_employeeId, _monthPeriod, token); } }
Class2(仅需取消令牌参数)
public class DocDownloadService : BaseDownloadService { public DocDownloadService() { // 直接适配无额外参数的API方法 DownloadFileDelegate = async (token) => await Api.GetMyDocFile(token); } }
关键说明
- 闭包捕获参数:子类的lambda表达式会捕获自身的参数(如
_employeeId),父类调用委托时无需关心这些参数,只负责传递取消令牌并处理统一返回的ReportFileModel。 - 类型安全:相比原代码的
object[],这种方式避免了类型转换的风险,同时保持了代码的可读性。 - 委托正确性:子类赋值的是委托实例(即方法的引用),而非直接执行API调用的结果,确保父类调用
ExecuteDownloadFile时才会触发API请求。
内容的提问来源于stack exchange,提问作者Val
相关产品推荐
相关产品推荐

