为什么可以为 EventCallback<DateTime> 类型的事件分配 void Foo(DateTime dt) 或 void Foo()?

Why can an event of type EventCallback<DateTime> be assigned either void Foo(DateTime dt) or void Foo()?

我是 Blazor webassembly 的新手,对以下内容感到困惑。我有一个名为 Earth.razor

的共享组件
<div>
    <button @onclick=@(() =>OnStop.InvokeAsync(DateTime.Now))>
        Stop Spinning
    </button>
</div>

@code
{
    [Parameter]
    public EventCallback<DateTime> OnStop { get; set; }
}

我在 Index.razor 页面中使用 Earth.razor 如下。

@page "/"

The earth stopped spinning at @(dt.ToString("hh:mm:ss")).

<Earth OnStop=StopHandler1 />

<Earth OnStop=StopHandler2 />

@code{

    private DateTime dt = DateTime.Now;
    private void StopHandler1()
    {
        this.dt = DateTime.Now;
    }

    private void StopHandler2(DateTime dt)
    {
        this.dt = dt;
    }
}

此处 OnStop 类型 EventCallback<DateTime> 的事件可以赋值 StopHandler1StopHandler2 ,它们的参数不同。

问题

为什么可能?

以下答案没有写在书上等等,纯属猜测,但我相信即使不是全部,也有一定程度的真实性。但是,这肯定是您问题的正确答案:

EventCallback 不是委托类型,而是根据需要生成委托的结构。

当您对 EventCallback<DateTime> OnStop 'delegate' 使用 OnStop=StopHandler1OnStop=StopHandler2 时,这两种方法都是可以接受的,尽管它们的签名不同,因为在幕后,正确的委托由系统提供(我不熟悉 Blazor 的内部结构,但这在我看来非常合理)。

如果您使用真正的委托(例如 Action 委托),则对同一个委托使用这两种方法将不起作用。如果你这样做:

 [Parameter]
public Action<DateTime> OnStop { get; set; }

这:<Earth OnStop=StopHandler1 /> 将不起作用,因为 StopHandler1 方法的签名不适合此处定义的 Action 委托。

希望这对您有所帮助...