The Wayback Machine - https://web.archive.org/web/20220124195632/https://github.com/dotnet/aspnetcore/issues/39734
Skip to content
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

Automatic type inference won't work when an EventCallBack<T> is added #39734

Open
1 task done
MariovanZeist opened this issue Jan 24, 2022 · 1 comment
Open
1 task done

Comments

@MariovanZeist
Copy link
Contributor

@MariovanZeist MariovanZeist commented Jan 24, 2022

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

Repo to demonstrate the Issue: https://github.com/MariovanZeist/BlazorInferenceCallback

Although my use case is for Table and Grid like components I will demonstrate the feature using a simpler component:

Assume this component: (A generic list component with a click event that has the clicked item as a parameter)

InferAndCallback.razor

@typeparam T
  //Hide non-important code to make this brief. full code in attached Repo
@code {
    [Parameter] public IEnumerable<T> Items { get; set; } = default!;
    [Parameter] public EventCallback<T> SelectEvent { get; set; } = default!;
}

We will supply the component with a List of Ingredient, and (optionally) supply a click event to handle selecting the ingredient.

index.razor

<InferAndCallBack Items=Ingredient.Ingredients />  //This will Compile without a callback

<InferAndCallBack Items=Ingredient.Ingredients SelectEvent=SelectedIngredient /> //Adding the Callback will not compile

<InferAndCallBack Items=Ingredient.Ingredients SelectEvent=SelectedIngredient T=Ingredient /> //Removing typeinference and specifying the type directly will make it compile again.

Last ingredient:@_ingredient

@code {
    private Ingredient? _ingredient;

    private Task SelectedIngredient(Ingredient selectedIngredient)
    {
        _ingredient = selectedIngredient;
        return Task.CompletedTask;
    }
}

Describe the solution you'd like

I would prefer to not have to specify the T type parameter directly, and instead, let it be inferred by the generated code.

so

<InferAndCallBack Items=Ingredient.Ingredients SelectEvent=SelectedIngredient />

Would compile without specifying the TypeParam

Additional context

This is probably due to how the source is generated:
I cleaned the generated source up a bit to show the difference, and the problem:

this is the relevant part of the generated source file: with comments to show the problem:

{
    [Microsoft.AspNetCore.Components.RouteAttribute("/")]
    public partial class Index : Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
		protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
		{
			//<InferAndCallBack Items=Ingredient.Ingredients />
			__Blazor.BlazorInferenceCallback.Pages.Index.TypeInference.CreateInferAndCallBack_0(__builder, 0, 1, Ingredient.Ingredients);
			//^ This compiles to and works correctly


			//<InferAndCallBack Items=Ingredient.Ingredients SelectEvent=SelectedIngredient />
			__Blazor.BlazorInferenceCallback.Pages.Index.TypeInference.CreateInferAndCallBack_1(__builder, 3, 4, Ingredient.Ingredients, 5, Microsoft.AspNetCore.Components.EventCallback.Factory.Create(this, SelectedIngredient));
			//^This fails because it generates an EventCallback instead of an EventCallback<T>
			// and the CreateInferAndCallBack_1 function expects an EventCallback<T>
			//It should be:
			//__Blazor.BlazorInferenceCallback.Pages.Index.TypeInference.CreateInferAndCallBack_1(__builder, 3, 4, Ingredient.Ingredients, 5, Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Ingredient>(this, SelectedIngredient));


			//<InferAndCallBack T=Ingredient Items=Ingredient.Ingredients SelectEvent=SelectedIngredient/>
			__builder.OpenComponent<BlazorInferenceCallback.Components.InferAndCallBack<Ingredient>>(7);
			__builder.AddAttribute(8, "Items", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Collections.Generic.IEnumerable<Ingredient>>(Ingredient.Ingredients));
			__builder.AddAttribute(9, "SelectEvent", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<Microsoft.AspNetCore.Components.EventCallback<Ingredient>>(Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Ingredient>(this, SelectedIngredient)));
			__builder.CloseComponent();
			//^As we specified the type, no type inference is needed so we can generate the code as any other non generic component
		}
	}
}
namespace __Blazor.BlazorInferenceCallback.Pages.Index
{
	#line hidden
	internal static class TypeInference
	{
		public static void CreateInferAndCallBack_0<T>(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder, int seq, int __seq0, global::System.Collections.Generic.IEnumerable<T> __arg0)
		{
			__builder.OpenComponent<global::BlazorInferenceCallback.Components.InferAndCallBack<T>>(seq);
			__builder.AddAttribute(__seq0, "Items", __arg0);
			__builder.CloseComponent();
		}
		public static void CreateInferAndCallBack_1<T>(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder, int seq, int __seq0, global::System.Collections.Generic.IEnumerable<T> __arg0, int __seq1, global::Microsoft.AspNetCore.Components.EventCallback<T> __arg1)
		{
			__builder.OpenComponent<global::BlazorInferenceCallback.Components.InferAndCallBack<T>>(seq);
			__builder.AddAttribute(__seq0, "Items", __arg0);
			__builder.AddAttribute(__seq1, "SelectEvent", __arg1);
			__builder.CloseComponent();
		}
	}
}
@MariovanZeist
Copy link
Contributor Author

@MariovanZeist MariovanZeist commented Jan 24, 2022

@javiercn I had another issue with Type inference, but as it was not related to constraints I created a separate Issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants