-
Notifications
You must be signed in to change notification settings - Fork 190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Blazor CascadingTypeParameter support - Current compiler cannot handle common scenarios. #10757
Comments
Hi @davidwengier nice train simulator! I am Melbourne based as well. If it helps, I notice that if the Widget.razor file uses an Action like this: [Parameter] public Action<T> Action { get; set; } Then you can use this code without specifying the type of i: <Widget Action="i => Console.WriteLine(i)" /> But if it is specified using EventCallback like this: [Parameter] public EventCallback<T> Action { get; set; } Then you you must specify the type of i either like this I have not looked under the covers, but note what WORKS and DOES NOT work below: EventCallbackFactory factory = new();
// This works
EventCallback<string> f1 = factory.Create<string>(null, i => Console.WriteLine(i));
// This works
EventCallback<string> f2 = factory.Create(null, (string i) => Console.WriteLine(i));
// This DOT NOT work
EventCallback<string> f3 = factory.Create(null, i => Console.WriteLine(i)); Thus, my assumption is that the Razor compiler is not emitting this as a call to I am guessing if the compiler emits the call to the cascaded type parameter, such as to |
Thanks for writing this up. If I'm reading it correctly, you are reporting two separate issues:
|
@jjonescz Yes I agree with your summary of point 1 that "if there is type inference involved - and where Action works, EventCallback should work similarly." I think this should be a simple change and would ideally get into .NET 9. I was surprised this did not work out of the box. I wasted a lot of time on it because I believed it must have been me doing something stupid instead of the compiler not supporting EventCallback in that particular and common case. Regarding point 2: Thank you for clarification and I agree with that it would be a breaking change so will need to be done through good documentation rather than a change (and I should not have included point 2 in the same bug/issue report - sorry). |
Hm, I've investigated the The razor compiler doesn't know the For example, for an CreateWidget(i => Console.WriteLine(i));
void CreateWidget<T>(Action<T> a) { } but for CreateWidget(EventCallback.Factory.Create(i => Console.WriteLine(i)); // error: the factory creates EventCallback instead of EventCallback<T>
void CreateWidget<T>(EventCallback<T> e) { } If runtime provided |
Is there an existing issue for this?
Is your feature request related to a problem? Please describe the problem.
I expected the CascadingTypeParameter feature to work in the most common and obvious scenarios, but it does not. If the cascaded type was a string, it should be possible to use
<Widget Action="item => Console.WriteLine(item)" />
instead of<Widget Action="(string item) => Console.WriteLine(item)" />
. If you were passing in a parameter, it should be possible to do this<Widget Item="Hello" />
instead of needing to do this<Widget Item="@("Hello")" />
. The CascadingTypeParameter feature was intended to resolve this type of issue but needs more work.Describe the solution you'd like
Imagine this repeater:
Then this Widget component intended to be used inside the repeater:
Warning: Do not overthink this widget as it is not intended to do anything sensible, other than demonstrate compiler limitations.
Now imagine we use the component like such:
The above code works, and
<Widget T="string" Action="i => Console.WriteLine(i)" />
also works. However, it is completely reasonable to expect to be able to use the following syntax:Another example of the compiler's mediocre compilation process is the following example. Let us say we write this code:
That works, but because T is a string, for consistency with the way the rest of blazor works, we would expect this to work (noting that it does work if the underlying type was a string instead of a type parameter, where the parameter was a string) :
However, this does not work (it looks for a member called Hello, which is what blazor would normally do for anything other than a string. Even this does NOT work:
<Widget T="string" Item="Hello" />
.@danroth27 and @SteveSandersonMS I had thought we were further along than this once we got to .NET 6 and added the CascadingTypeParameter feature. It is hard, not being on the compiler team, to understand why when an outer component uses CascadingTypeParameter, that that isn't the same as directly passing in the type using the old-school
T="string"
approach. But I do feel the current expectation means almost everyone will hit this issue and get stuck/frustrated.Is there a concrete reason why the situation cannot be improved for .NET 9 or even .NET 10 if that is needed.
Additional context
No response
The text was updated successfully, but these errors were encountered: