You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现子类向父类传递参数不同但返回值统一的回调委托?

解决方案

首先修正核心问题:你的原代码存在两个关键问题——父类委托签名设计冗余,且子类错误地直接赋值了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:34:59