【问题标题】:Is it possible to override the generic type in a factory method for abstract classes?是否可以在抽象类的工厂方法中覆盖泛型类型?
【发布时间】:2013-01-31 17:09:41
【问题描述】:

我有一个工厂类,它返回从抽象类型继承的具体实例。这些具体实例还具有其数据类型的通用属性,因为每个实例都需要不同的数据类型。 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&lt;ExampleClass&gt;(myStringArray) 时,我收到一个错误,提示它需要可转换为 AbstractClass&lt;object&gt;

有没有更好的方法来做我想做的事情?

【问题讨论】:

  • 您指的是 AbstractClass、AbstractBase 和 AbstractBaseClass。只是很多错别字?
  • 是的,哎呀。我从头开始重新输入它,因为它比将我正在处理的代码更容易地清理为 SO 问题清晰易读的东西。修好了。

标签: c# generics abstract-class


【解决方案1】:

这就是问题所在:

where TType : AbstractClass<object>

那个约束正是编译器抱怨的那个。

听起来你真的想要这样的东西:

public static TContainer CreateNewClass<TContainer, TData>(TData data) 
    where TContainer : AbstractClass<TData>, new()

不幸的是,这需要您为方法指定 both 类型参数 - 但至少就您使用的数据类型而言,它是安全的。您可以通过创建两个通用方法和一个在它们之间使用的单独类来解决此问题,允许您编写如下内容:

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&lt;AbstractClass&gt;;您不会以编译时安全的方式知道每个条目的数据类型...这是完全有意义的,因为每个元素都可以使用不同的类型。

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

【讨论】:

    猜你喜欢
    • 2012-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    相关资源
    最近更新 更多