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

如何在类中使用带泛型方法的抽象类ResourceFilter作为属性

解决方法

要解决泛型抽象类无法直接作为非泛型属性类型的问题,你需要定义一个非泛型的基础抽象类/接口,让泛型的ResourceFilter<TFilter>继承它,以此实现统一类型的声明。

步骤1:创建非泛型抽象基类

先定义一个不带泛型参数的抽象类,封装所有不依赖TFilter的核心成员:

public abstract class ResourceFilterBase : SomeOtherClass
{
    protected ResourceFilterBase(string name, string friendlyName)
        : base(name, friendlyName)
    {
    }

    public abstract string GetFilterDisplay(object filter);
    public abstract string GetFilterValue(object filter);
    public virtual string GetComparisonValue(object compare)
    {
        return Value + "_" + GetFilterValue(compare);
    }
    public abstract object GetDefaultFilter();
}

步骤2:修改泛型抽象类继承非泛型基类

让原泛型类继承新的非泛基类,同时保留泛型版本的方法供子类实现:

public abstract class ResourceFilter<TFilter> : ResourceFilterBase
{
    public static readonly ResourceFilter<ActorTypeEnum> ActorType = new ActorTypeResourceFilter();

    protected ResourceFilter(string name, string friendlyName)
        : base(name, friendlyName)
    {
    }

    // 实现非泛型基类方法,内部转调泛型版本
    public override string GetFilterDisplay(object filter)
    {
        return GetFilterDisplay(TypeCheck(filter));
    }

    public override string GetFilterValue(object filter)
    {
        return GetFilterValue(TypeCheck(filter));
    }

    public override object GetDefaultFilter()
    {
        return GetDefaultFilterTyped();
    }

    // 泛型版本的抽象方法,供子类实现具体逻辑
    public abstract string GetFilterDisplay(TFilter filter);
    public abstract string GetFilterValue(TFilter filter);
    public abstract TFilter GetDefaultFilterTyped();

    protected TFilter TypeCheck(object value)
    {
        if (value is null)
            throw new ArgumentNullException(nameof(value));

        if (value is TFilter expectedType)
            return expectedType;

        throw new FriendlyException($"Type {value.GetType()} is not valid for this Resource Filter");
    }
}

步骤3:调整实现类逻辑

修改ActorTypeResourceFilter,实现泛型版本的抽象方法即可:

public sealed class ActorTypeResourceFilter : ResourceFilter<ActorTypeEnum>
{
    internal ActorTypeResourceFilter()
        : base(nameof(ActorType), "Actor Type")
    {
    }

    public override string GetFilterDisplay(ActorTypeEnum filter)
    {
        return filter.FriendlyName;
    }

    public override string GetFilterValue(ActorTypeEnum filter)
    {
        return filter.Name;
    }

    public override ActorTypeEnum GetDefaultFilterTyped()
    {
        return ActorTypeEnum.User;
    }
}

步骤4:在目标类中使用非泛型类型

现在就可以直接在ClassToApplyResourceFilter中用非泛型基类作为属性类型了:

public class ClassToApplyResourceFilter
{
    public ResourceFilterBase ResourceFilter { get; private set; }
}

补充说明

这种设计既保留了泛型的类型安全性(子类实现时仍针对具体TFilter做逻辑),又满足了统一类型声明的需求。如果不想修改太多原有代码,也可以用非泛型接口IResourceFilter替代抽象基类,效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:12:33