如何返回带泛型类型的抽象类?工厂方法实现疑问
解决方案分析与实现
你的核心问题在于:泛型抽象类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
相关产品推荐
相关产品推荐

