C#扩展方法(Extension Method)

在 C# 中,扩展方法(Extension Method)的语法允许你通过 this 关键字将第一个参数隐式传递,因此在调用时 ​不需要显式传递第一个参数。

这里有个扩展方法

csharp 复制代码
public static Task<T> InvokeAsync<T>(this Control control, Func<T> func)
{
    var tcs = new TaskCompletionSource<T>();
    control.BeginInvoke(new Action(() =>
    {
        try
        {
            tcs.SetResult(func());
        }
        catch (Exception ex)
        {
            tcs.SetException(ex);
        }
    }));
    return tcs.Task;
}

扩展方法的特点:

复制代码
**​隐式 control 参数:**
    this Control control 表示这是一个扩展方法,作用在 Control 类型上。
    当你调用 _uiControl.InvokeAsync(showDialogFunc) 时,_uiControl 会自动作为 control 参数传递,而 showDialogFunc 是第二个参数 func。
**​泛型参数 <T>:**
    InvokeAsync<T> 的泛型参数 <T> 会根据 func 的返回值类型自动推断。例如,如果 showDialogFunc 返回 string,则 T 会被推断为 string。

调用时的参数传递:

csharp 复制代码
return await _uiControl.InvokeAsync(showDialogFunc);
复制代码
_uiControl 是扩展方法的第一个参数 control(通过 this Control control 隐式传递)。
showDialogFunc 是第二个参数 func。

为什么不需要显式传递两个参数?

扩展方法的语法简化了调用方式:

原本需要写为 InvokeAsync(_uiControl, showDialogFunc)。

但因为 this Control control 的存在,你可以直接写成 _uiControl.InvokeAsync(showDialogFunc),编译器会自动将 _uiControl 作为第一个参数。

完整流程解析:

线程切换:

如果当前线程不是 UI 线程,control.BeginInvoke 会将 func 委托的调用调度到 UI 线程。

如果当前已经是 UI 线程,BeginInvoke 会直接执行(同步或异步取决于具体实现)。
​异步包装:

TaskCompletionSource 用于将 BeginInvoke 的异步操作包装成一个 Task。
当 func 在 UI 线程执行完成后:

如果成功,调用 tcs.SetResult(func()) 设置结果。

如果抛出异常,调用 tcs.SetException(ex) 传递异常。
​ 返回 Task:

最终返回的 tcs.Task 可以让调用者通过 await 等待结果。

总结:

​**扩展方法的语法:通过 this 关键字隐式传递第一个参数(control),调用时不需要显式传递。
​
泛型推断:**根据 func 的返回值类型自动推断泛型参数 。
​线程安全: BeginInvoke 确保 func 在 UI 线程执行,并通过 Task 提供异步支持。

相关推荐
电商API_180079052476 小时前
反向海淘多币种结算:汇率该在哪个时点被冻结
java·开发语言·数据库·跨境电商·1688 api
开开心心就好7 小时前
多份文档怎么批量打印?支持多种格式
java·服务器·开发语言·pdf·ocr·散列表·启发式算法
Want5957 小时前
Python炫酷烟花①
开发语言·python
星夜离尘568 小时前
MATLAB 线性去趋势为何损伤低频正弦:联合最小二乘估计幅相与漂移
开发语言·matlab
用户788477316348 小时前
用 C# 把每周 6 小时的 PDF 录入干到 20 分钟:一份可复制的桌面 OCR 方案
c#
程序员清风8 小时前
双指针与滑动窗口:高效处理连续区间
开发语言·算法
开开心心就好9 小时前
文件被占用删不掉?解锁工具强制删除
java·运维·服务器·开发语言·前端·pdf·ocr
云和数据.ChenGuang9 小时前
python大小整数范围解析
java·开发语言·python
fensnote9 小时前
西门子 S7 PLC 内部寄存器读写 Demo(C 语言)
c语言·开发语言
benchmark_cc10 小时前
量化项目启动时,应该先设计数据接口还是先编写策略?从系统架构角度做出正确选择
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash