2

我有一个工厂类,它返回从抽象类型继承的具体实例。这些具体实例还具有其数据类型的通用属性,因为每个实例都需要不同的数据类型。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>

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

4

1 回答 1

3

好吧,这就是问题所在:

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

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

于 2013-01-31T17:13:21.177 回答