是否可以在抽象类的工厂方法中重写泛型类型
本文关键字:方法 重写 泛型类型 工厂 抽象类 是否 | 更新日期: 2023-09-27 17:56:56
我有一个工厂类,它返回从抽象类型继承的具体实例。这些具体实例还具有其数据类型的泛型属性,因为每个实例都需要不同的数据类型。Data 属性也存在于抽象类型上,因为它是在工厂中设置的。
public static class FactoryClass
{
public static TType CreateNewClass<TType>(object data)
where TType : AbstractClass<object>, new()
{
var newClass = new TType {Data = data};
// do some stuff
// keep track of all created types in a list
List.Add(newClass);
return newClass;
}
private List<AbstractClass<object>> MyList = new List<AbstractClass<object>>()
}
public abstract class AbstractClass<TData>
{
internal AbstractClass()
{
// do constructor things
}
protected SomeCommonFunction()
{
// common code for abstract base class
}
public abstract void DoSomethingToData();
TData Data;
}
public class ExampleClass : AbstractClass<string[]>
{
public override void DoSomethingToData()
{
// sort the strings or something
// call the abstract code
}
}
当我尝试调用FactoryClass.CreateNewClass<ExampleClass>(myStringArray)
时,我收到一个错误,提示它需要可转换AbstractClass<object>
有没有更好的方法来做我想做的事情?
嗯,这就是问题所在:
where TType : AbstractClass<object>
该约束正是编译器抱怨的约束。
在我看来,你真的想要这样的东西:
public static TContainer CreateNewClass<TContainer, TData>(TData data)
where TContainer : AbstractClass<TData>, new()
不幸的是,这需要您为该方法指定两个类型参数 - 但至少就您使用的数据类型而言,它是安全的。您可以通过创建两个泛型方法和一个单独的类来解决此问题,以便在它们之间使用,从而允许您编写类似以下内容的内容:
FactoryClass.For(myStringArray).CreateNewClass<ExampleClass>();
For
方法将返回一个类型参数为 string[]
的泛型类型,然后CreateNewClass
将是一个实例方法,该方法采用数据类型的容器类型。
但是,您的列表根本无法以当前形式工作。您可能希望为 AbstractClass
创建一个非泛型基类:
public abstract class AbstractClass
{
// Anything which doesn't use TData
}
然后:
public abstract class AbstractClass<TData> : AbstractClass
此时,工厂中的列表将是一个List<AbstractClass>
;您不会以编译时安全的方式知道每个条目的数据类型...这是完全有意义的,因为每个元素都可以使用不同的类型。
(哦,当然,如果你想从静态方法访问它,你的列表字段需要是静态的......