[Feature] Support enumerable/collection interfaces for bindable parameters/`EventCallback<T>`
- Dominant language
- C#
- Stars
- 20.7k
- Forks
- 4.3k
- PR merge metrics
- PR metrics pending
Description
Currently Razor doesn't seem to support binding to a parameter that is a generic collection interface from something that implements that interface. It will produce an error along the lines of:
Argument 10: cannot convert from 'Microsoft.AspNetCore.Components.EventCallback>' to 'Microsoft.AspNetCore.Components.EventCallback>'
Of course this issue isn't specific to collections (or interfaces), but they seem to be the area that would require the least amount of effort while also providing the most value.
Two things that come to mind:
1. `EventCallback` may need to be made covariant (or maybe I am reversing that)?
2. Or, perhaps the code generator just needs to pay attention to the type of the parameter instead of the type of the object it is being bound to?
In both cases, the generated delegate would need to know to handle the "known" collections and their conversions, i.e. use methods like `Enumerable.ToList()` when necessary.
A simplified but contrived example:
```razor
@code
{
List strings = [ "a", "bunch", "of", "strings" ];
HashSet importantStrings = [];
}
@* FindImportantStrings.ImportantStrings is a [Parameter]IEnumerable*@
```
This would generate an error like the one above, which forces components to be opinionated/lock down the types of collections the consuming developer uses or the author has to create a variant of the component for each type of collection they might want to support.
It's probably worth pointing out that `AllStrings` could also be an `IEnumerable` and, as we would expect, there is no problem assigning a `List` to it.
But it seems like all (easier said than done, I'm sure) that needs to happen is that the code generator could check the types involved and see if they are different and if they are, then generate code that:
1. Calls the appropriate `Enumerable` conversation method.
2. Or, ideally, just uses the spread operator and lets the compiler take care of calling the appropriate conversion method.
Possible problems: I suppose it is possible that there are some semantics with binding that require or expect the source and destination to be the same object and not copies, at least in the case of reference types. If that is the case, then maybe there could just be some way to opt in (or out?) to this, e.g. `[Parameter(convertCollections = true)]`.
Contributor guide
Assessment
This issue has not been assessed yet.