Использование Generi c типов с наследованием в компоненте Blazor - PullRequest
0 голосов
/ 15 апреля 2020

Я пытаюсь создать компонент "generi c list" в Blazor и хочу, чтобы этот компонент мог принимать любой объект, производный от базового класса. Мой код в настоящее время, как показано ниже:

Базовый класс:

    public class Model
    {

        // PK for the record
        [Key]
        public int Id { get; set; }

        // holds the front-end name for the record
        [Required(ErrorMessage = "Name is required")]
        public string Name { get; set; } = "";

        // holds the date and time the record was created
        [Required(ErrorMessage = "Created Timestamp is required")]
        public DateTime Created { get; set; } = DateTime.Now;

        // holds the username of the person who created the record
        [Required(ErrorMessage = "Creating user is required")]
        public string CreatedBy { get; set; } = "";


        // holds the date and time the record was updated
        public DateTime Updated { get; set; } = new DateTime(0);

        // holds the username of the person who last updated the record
        public string UpdatedBy { get; set; } = "";

    }

Производный класс:

public class ModelDesc: Model
    {

        // holds the description of the stakeholder
        public string Description { get; set; }

    }

компонент определен как ниже; DisplayGenericList.razor:

@typeparam T 


<h3>DisplayGenericList</h3>

@foreach (T lpObj in ListItems)
{
    <span>@lpObj.Name, @lpObj.Id</span>
}

@code {


    [Parameter]
    /// <summary>
    /// Contains the list of items to be shown in the list
    /// </summary>
    public List<T> ListItems { get; set; }
}

}

с DisplayGenericList.razor.cs , как показано ниже;

    public partial class DisplayGenericList<T> where T:Model
    {
    }

Это само по себе компилируется, однако, когда я пытаюсь использовать компонент на странице, я получаю следующую ошибку; CS0314 The type 'T' cannot be used as type parameter 'T' in the generic type or method 'DisplayGenericList<T>'. There is no boxing conversion or type parameter conversion from 'T' to 'ProjectName.Data.Interfaces.Model'.

index.razor - это просто;

@page "/"

@using ProjectName.Data.Models

@using ProjectName.Shared.Components.Generics

<h1>Hello, world!</h1>

Welcome to your new app.



<hr />

<DisplayGenericList ListItems="lItems" />


@code
{

    private List<ModelDesc> lItems = new List<ModelDesc>()
    {
        new ModelDesc() {Name = "Item 1", Description = "Description 1", Created = DateTime.Now, CreatedBy = "User 1"},
        new ModelDesc() {Name = "Item 2", Description = "Description 2", Created = DateTime.Now, CreatedBy = "User 1"},
        new ModelDesc() {Name = "Item 3", Description = "Description 3", Created = DateTime.Now, CreatedBy = "User 2"},
        new ModelDesc() {Name = "Item 4", Description = "Description 4", Created = DateTime.Now, CreatedBy = "User 2"},
        new ModelDesc() {Name = "Item 5", Description = "Description 5", Created = DateTime.Now, CreatedBy = "User 3"}
    };

}

Я довольно новичок в Blazor, и поэтому я подозреваю, что я что-то делаю неправильно, однако может ли кто-нибудь посоветовать, что я должен делать здесь для обеспечения (и использования) ограничения на компонент?

1 Ответ

1 голос
/ 15 апреля 2020

Обходной путь - явное добавление TypeParam в использование компонента; поэтому тот же код, что и в примере из исходного вопроса, но с изменением реализации компонента index.razor следующим образом:

<DisplayGenericList ListItems="lItems" T="ModelDesc" />

Это было помечено как запрос функции, как нашло @Vencovsky выше и хотя ограничения типов поддерживаются в базовых классах Blazor, компилятор не может применить ограничение без явного определения типа, как указано выше.

...