You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为抽象基类Thing实现带动态枚举的IsInList方法(适配Blazor)

问题描述

我有不同类型的Item,每种Item都有存储ID的枚举。希望为抽象基类Thing实现一个方法用于检查Item的ID是否在指定列表中,但不想采用Thing<T>泛型基类方案(避免Blazor UI组件和页面代码混乱)。同时需要实现:

  • Blazor组件接收Thing类型参数,统一展示所有子类实例
  • 在页面中直接调用Thing实例的IsInList方法判断是否在指定列表中

原示例代码存在编译问题,核心是要在非泛型基类的前提下,让子类各自处理枚举ID的校验逻辑。


可行实现方案

1. 重构抽象基类

将ID定义为object类型,IsInList方法接收非泛型IEnumerable参数,让子类自行处理类型匹配:

public abstract class Thing
{
    public string Name { get; set; }
    public int Amount { get; set; }
    // 子类返回自身的枚举ID
    public abstract object ID { get; }
    // 检查当前ID是否在目标列表中
    public abstract bool IsInList(IEnumerable list);
}

2. 子类具体实现(以Fruit为例)

子类定义自身枚举,实现基类的ID属性和IsInList方法,先做类型校验再检查包含关系:

public class Fruit : Thing
{
    public enum FruitIds
    {
        F_NotSet,
        F_Banana,
        F_Apple
    }

    public FruitIds CurrentId { get; set; } = FruitIds.F_NotSet;

    // 实现基类ID属性,返回当前枚举值
    public override object ID => CurrentId;

    public override bool IsInList(IEnumerable list)
    {
        // 校验列表类型是否匹配当前枚举
        if (list is List<FruitIds> fruitList)
        {
            return fruitList.Contains(CurrentId);
        }
        return false;
    }
}

3. Blazor UI组件(ThingViewer)

组件直接接收Thing类型参数,展示通用属性:

<div>@Thing.Name [@Thing.Amount]</div>

@code {
    [Parameter] public Thing Thing { get; set; }
}

4. 页面复用组件与调用IsInList

页面维护List<Thing>实例和对应枚举列表,循环调用即可:

<div>
    @foreach (var thing in MyThings)
    {
        @if (thing.IsInList(OfferFruitIds))
        {
            <div class="offer">
                <ThingViewer Thing="thing" />
            </div>
        }
        else
        {
            <ThingViewer Thing="thing" />
        }
    }
</div>

@code {
    private List<Thing> MyThings = new List<Thing>
    {
        new Fruit { Name = "香蕉", Amount = 10, CurrentId = Fruit.FruitIds.F_Banana },
        new Fruit { Name = "苹果", Amount = 5, CurrentId = Fruit.FruitIds.F_Apple }
    };

    // 优惠的水果ID列表
    private List<Fruit.FruitIds> OfferFruitIds = new List<Fruit.FruitIds>
    {
        Fruit.FruitIds.F_Banana
    };
}

可选优化:类型安全重载

为了避免直接传IEnumerable的类型模糊,可给基类增加泛型重载方法,子类无需修改即可支持类型安全调用:

public abstract class Thing
{
    // ... 原有成员

    // 类型安全的重载入口,默认调用非泛型版本
    public bool IsInList<T>(IEnumerable<T> list)
    {
        return IsInList((IEnumerable)list);
    }
}

页面中可直接用类型安全的方式调用:thing.IsInList(OfferFruitIds)


内容的提问来源于stack exchange,提问作者javirs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 16:46:17