我正在尝试在 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 还很陌生,所以我怀疑我做错了什么,但是谁能建议我在这里应该做什么来强制(和使用)组件的约束?
最佳答案
一种解决方法是在组件用法中显式添加 TypeParam;所以与原始问题中的示例代码相同,但将组件的 index.razor 实现更改如下;
<DisplayGenericList ListItems="lItems" T="ModelDesc" />
这已被标记为功能请求,正如上面的@Vencovsky 所发现的那样,虽然底层 Blazor 类支持类型约束,但如果没有按照上面明确定义的类型,编译器无法强制执行约束。
关于c# - 在 Blazor 组件中使用具有继承的泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61223459/