Search code examples
c#blazorblazor-client-side

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


I am new to Blazor webassembly and get confused with the following. I have a shared component named Earth.razor

<div>
    <button @onclick=@(() =>OnStop.InvokeAsync(DateTime.Now))>
        Stop Spinning
    </button>
</div>

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

I use the Earth.razor in my Index.razor page as follows.

@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;
    }
}

Here OnStop event of type EventCallback<DateTime> can be assigned either StopHandler1 and StopHandler2 which are different in arguments.

Question

Why is it possible?


Solution

  • The following answer is not written in books, etc., it is a mere guesswork, but I believe it is true to some extent if not to all. However, it is certainly the correct answer to your question:

    EventCallback is not a delegate type but a struct that produces delegates as necessary.

    When you use OnStop=StopHandler1 and OnStop=StopHandler2 for the EventCallback<DateTime> OnStop 'delegate', both methods are tolerated, though their signature differ, because behind the scenes, the correct delegate is provided by the system (I'm not acquainted with the internals of Blazor, but this seems to me very reasonable).

    If you use a real delegate such as the Action delegate using both method for the same delegate won't work. If you do something like this:

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

    This: <Earth OnStop=StopHandler1 /> won't work, as the signature of the StopHandler1 method is not suitable for the Action delegate defined here.

    Hope this helps...