Как создать универсальный тип, который должен наследовать от класса с универсальным типом в Blazor?

Я пытаюсь создать класс, который имеет 3 общих типа, и один из типов должен наследовать от другого класса, у которого есть другие 2 общих типа.

Что мне действительно нужно, так это то, что IForm наследуется от FormComponent так что все его методы реализованы.

Form.razor

@typeparam TForm
@typeparam TModel
@typeparam TResult

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

Form.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

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

    public abstract TResult OnValidSubmit();

    // ... 
    // some other properties   
}

Код, из которого я использую форму

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

Но это дает мне ошибку

Ошибка CS0314 Тип TForm нельзя использовать в качестве параметра типа TForm в универсальном типе или методе Form. Преобразование упаковки или преобразование параметров типа из TForm в Core.Web.Base.FormComponentотсутствует.

Я искал эту ошибку во многих местах, но не нашел ни одного случая, когда было бы 3 общих типа. Я также читал документы, но не мог использовать их для решения своего дела.

2 ответа

Просто узнайте, что эта проблема связана с тем, что blazor еще не поддерживает ограничения типа.

@juharr спросил, не использую ли я его в другом месте. Я сказал нет, но на самом деле я использую его в компоненте Blazor, и у него еще нет такой поддержки;/

Сделайте свой универсальный компонент только компонентом класса. Таким образом вы можете добавить свои ограничения

Я думаю, что стоит поделиться найденным мной обходным путем - просто добавьте файл кода программной части в свой компонент и укажите там ограничения.

Кредиты на этот ответ, который привел меня к успеху...

Шаги по добавлению ограничения в MyComponent.razor:

  1. Добавить -> Создать -> Класс, назовите файл MyComponent.razor.csи убедитесь, что он создан в той же папке, что и MyComponent.razor. Если все работает нормально, файл следует добавить как суб-файл или MyComponent.razor.cs...

  2. открыто MyComponent.razor.cs. Убедитесь, что пространство имен такое же, как у компонента (должно быть нормально, если класс был создан в той же папке)

  3. Отметьте класс как public partial и добавьте свои ограничения

    // убедитесь, что пространства имен соответствуют общедоступному частичному классу MyComponent, где TItem: MyBaseClass, new() {

Вот и все. И даже лучше, теперь я могу внедрить общий сервис в свой компонент в MyComponent.razor составная часть:

@typeparam TItem

@inject MyGenericService<TItem> _genericService;

Обратите внимание, что я зарегистрировал сервис в Startup.cs как синглтон (не тестировал область видимости, но тоже должен работать)...

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

Надеюсь, это сработает для других, это сделало мои общие CRUD-формы НАМНОГО проще в работе и сохранило огромное количество дублированного кода и странных переключателей на вывод типа из общего управления!

Другие вопросы по тегам