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

如何返回带泛型类型的抽象类?工厂方法实现疑问

解决方案分析与实现

你的核心问题在于:泛型抽象类OpStrategy<T>的不同具体实现绑定了固定的类型(int/string),它们对应的OpStrategy<int>和OpStrategy<string>是完全不同的类型,无法用单一的泛型返回类型或非泛基类直接统一返回。下面给出三种可行的实现方案,你可以根据场景选择:

方案一:引入非泛型基接口(推荐,兼顾灵活性与类型安全)

先定义一个非泛型的接口作为所有策略的统一契约,让泛型抽象类实现该接口:

// 新增非泛型接口,作为统一返回类型
public interface IOpStrategy
{
    bool Apply(object a, object b);
}

// 泛型抽象类实现非泛型接口
public abstract class OpStrategy<T> : IOpStrategy
{
    public abstract bool Apply(T a, T b);

    // 显式实现非泛型接口,做类型校验与转换
    bool IOpStrategy.Apply(object a, object b)
    {
        if (a is not T typedA || b is not T typedB)
            throw new ArgumentException($"参数类型必须为{typeof(T).Name}");
        return Apply(typedA, typedB);
    }
}

// 原具体策略类无需修改
public class EqConcreteStrategy : OpStrategy<int>
{
    public override bool Apply(int a, int b)
    {
        return a.Equals(b);
    }
}

public class NeqConcreteStrat : OpStrategy<string>
{
    public override bool Apply(string a, string b)
    {
        return !a.Equals(b);
    }
}

然后实现工厂方法,返回非泛型接口类型:

public static IOpStrategy GetStrategy(string operatorType)
{
    return operatorType switch
    {
        "eq" => new EqConcreteStrategy(),
        "neq" => new NeqConcreteStrat(),
        _ => throw new ArgumentOutOfRangeException(nameof(operatorType), "不支持的操作符类型")
    };
}

调用示例:

// 针对int类型的相等判断
int numA = 10, numB = 10;
var eqStrategy = GetStrategy("eq");
bool eqResult = eqStrategy.Apply(numA, numB); // 返回true

// 针对string类型的不等判断
string strA = "hello", strB = "world";
var neqStrategy = GetStrategy("neq");
bool neqResult = neqStrategy.Apply(strA, strB); // 返回true

方案二:使用动态类型(最简单,但无编译时类型安全)

直接让工厂返回dynamic类型,绕开编译时类型检查:

public static dynamic GetStrategy(string operatorType)
{
    switch (operatorType)
    {
        case "eq":
            return new EqConcreteStrategy();
        case "neq":
            return new NeqConcreteStrat();
        default:
            throw new ArgumentOutOfRangeException(nameof(operatorType));
    }
}

调用示例:

var strategy = GetStrategy("eq");
bool result = strategy.Apply(5, 5); // 编译时不检查类型,运行时类型不匹配会报错

这种写法最简洁,但失去了编译时类型校验,适合内部确定类型不会出错的场景。

方案三:泛型工厂+类型约束(强类型安全,但调用需明确指定类型)

让工厂方法接收泛型参数,并校验操作符与类型的匹配关系:

public static OpStrategy<T> GetStrategy<T>(string operatorType)
{
    if (typeof(T) == typeof(int) && operatorType == "eq")
        return new EqConcreteStrategy() as OpStrategy<T>;
    if (typeof(T) == typeof(string) && operatorType == "neq")
        return new NeqConcreteStrat() as OpStrategy<T>;
    
    throw new NotSupportedException($"不支持类型{typeof(T)}与操作符{operatorType}的组合");
}

调用示例:

// 必须明确指定泛型类型
var eqStrategy = GetStrategy<int>("eq");
bool eqResult = eqStrategy.Apply(3, 3);

var neqStrategy = GetStrategy<string>("neq");
bool neqResult = neqStrategy.Apply("foo", "bar");

这种方式有严格的编译时类型安全,但调用时必须指定正确的类型与操作符组合,否则会抛出异常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:30:18