简体   繁体   English

如何在 Blazor 中创建一个必须从具有泛型类型的类继承的泛型类型?

[英]How to make a generic type that must inherit from a class with generic type in Blazor?

I'm trying to make a class that have 3 generic types and one of the types must inherit from that other class that have the other 2 generic types.我正在尝试创建一个具有 3 个泛型类型的类,其中一个类型必须从具有其他 2 个泛型类型的另一个类继承。

What I really need is that IForm inherits from FormComponent so it have all of it's methods implemented.我真正需要的是IForm继承自FormComponent因此它有所有实现它的方法。

Form.razor Form.razor

@typeparam TForm
@typeparam TModel
@typeparam TResult

<EditForm Model="@Model" OnValidSubmit="@HandleValidSubmit">
    @ChildContent
</EditForm>

Form.razor.cs表格.razor.cs

public partial class Form<TForm, TModel, TResult>  
    where TForm : FormComponent<TModel, TResult>
{

    [Parameter]
    public TForm FormRef { get; set; }

    [Parameter]
    public EventCallback<TResult> OnValidSubmit { get; set; }

    [Parameter]
    public TModel Model { get; set; }

    // ... 
    // some other properties
}

FormComponent.cs表单组件.cs

public abstract class FormComponent<TModel, TResult> : BaseDomComponent
{        
    [CascadingParameter]
    public TModel Model { get; set; }

    public abstract TResult OnValidSubmit();

    // ... 
    // some other properties   
}

Code from where I use Form我使用 Form 的地方的代码

<Form Model="@Entity" FormRef="@_formRef" OnValidSubmit="@HandleValidSubmit">
    <XYZForm @ref="_formRef" />
    <Button ButtonType="ButtonType.Submit">Submit</Button>
</Form>

But this gives me the error但这给了我错误

Error CS0314 The type 'TForm' cannot be used as type parameter 'TForm' in the generic type or method 'Form< TForm, TModel, TResult >'.错误 CS0314 类型“TForm”不能用作泛型类型或方法“Form<TForm、TModel、TResult>”中的类型参数“TForm”。 There is no boxing conversion or type parameter conversion from 'TForm' to 'Core.Web.Base.FormComponent< TModel, TResult >'没有从 'TForm' 到 'Core.Web.Base.FormComponent< TModel, TResult >' 的装箱转换或类型参数转换

I searched this error in alot of places but didn't found any case where there was 3 generic types.我在很多地方搜索了这个错误,但没有发现任何有 3 种泛型类型的情况。 I also read the docs but couldn't use that to solve my case.我也阅读了文档,但无法使用它来解决我的案例。

Just find out this issue is about blazor not supporting type constraints yet.只是发现这个问题是关于 blazor还不支持类型约束

@juharr asked if I was using it in another place. @juharr 问我是否在其他地方使用它。 I said no, but acctually I'm using it in the blazor component, and it doesn't have that support yet ;/我说不,但实际上我在 blazor 组件中使用它,但它还没有这种支持;/

Make your generic component a class component only.使您的通用组件仅成为类组件。 That way you can add your constraints这样你就可以添加你的约束

I think it's worth sharing the workaround I found - simply add a code-behind file to your component and specify the constraints there.我认为值得分享我发现的解决方法 - 只需将代码隐藏文件添加到您的组件并在那里指定约束。

Credits to this answer that led me to success...归功于这个让我成功的答案......

Steps to add the constraint to MyComponent.razor :将约束添加到MyComponent.razor步骤:

  1. Add -> New -> Class, name the file MyComponent.razor.cs and make sure it is created in the same folder as the MyComponent.razor .添加 -> 新建 -> 类,将文件命名为MyComponent.razor.cs并确保它与MyComponent.razor同一文件夹中创建。 If all works fine, the file should be added as a sub-file or MyComponent.razor.cs ...如果一切正常,则应将该文件添加为子文件或MyComponent.razor.cs ...

  2. Open MyComponent.razor.cs .打开MyComponent.razor.cs Make sure that the namespace is the same as the component (should be ok if the class was created in the same folder)确保命名空间与组件相同(如果类是在同一个文件夹中创建的应该没问题)

  3. Mark the class as public partial and add your constraints将该类标记为public partial并添加您的约束

    // make sure namespaces match public partial class MyComponent where TItem : MyBaseClass, new() { // 确保命名空间匹配公共部分类 MyComponent where TItem : MyBaseClass, new() {

And that's it.就是这样。 And even better, I can now inject a generic service to my component to the MyComponent.razor component:更好的是,我现在可以将通用服务注入到MyComponent.razor组件中:

@typeparam TItem

@inject MyGenericService<TItem> _genericService;

Note that I registered the service in Startup.cs as a singleton (didn't test scoped but should work as well)...请注意,我在Startup.cs将该服务注册为单例(没有测试范围,但应该也能正常工作)...

// --- `Startup.cs` code
services.AddSingleton(new MyGenericService<MyObject>());

Hope this works for others, it made my generic CRUD forms SO MUCH easier to deal with and saved huge amount of duplicate code and weird switches to infert type from generic control!希望这对其他人有用,它使我的通用 CRUD 表单更容易处理并节省了大量重复代码和奇怪的开关以从通用控件推断类型!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM