c# - 是否可以在抽象类的工厂方法中重写泛型类型?

标签 c# generics abstract-class

我有一个工厂类,它返回从抽象类型继承的具体实例。这些具体实例还具有其数据类型的通用属性,因为每个实例都需要不同的数据类型。 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> ;您不会以编译时安全的方式知道每个条目的数据类型...这完全有意义,因为每个元素可以使用不同的类型。

(哦,当然,如果您想从静态方法访问列表字段,则列表字段需要是静态的......)

关于c# - 是否可以在抽象类的工厂方法中重写泛型类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14631319/

相关文章:

c# - 如何使用方法实现基类并强制派生类覆盖它?

c# - 如何在 Asp.Net Core 的 ExceptionFilterAttribute 中传递 TempData

c# - InsertFile 的 OpenXML SDK 替代方案是什么?

c# - 无法从 'SpecificComponent' 转换为 'IComponent<IComponentGuid>'

java - 像在 C# 中一样解决 Java 中的泛型方法、泛型参数类型?

java - 抽象类中的疑问

Django:抽象类中的自定义模型管理器查询

c# - 使用 Serializable() 从 XML 文件中填充一个数组

c# - 该进程无法访问文件 '.mdf',因为该文件正在被另一个进程使用

ios - ViewController 可以是包含 IBOutlets 等的通用吗?