声明一个基类数组并实例化继承的成员

时间:2011-02-18 09:11:44

标签: c# inheritance generics

我有一个用泛型定义的类:

public class GenericDataStore<T>
{
     // UnderlyingDataStore is another class that manages a queue, or a linked list
     private UnderlyingDataStore<T> dataQueue = new UnderlyingDataStore<T>();
     public void addData(T data) { dataQueue.Add(data); }
     public T getLastData() { dataQueue.getLastData(); }
}

然后我根据这个类有不同的派生类:

public class ByteDataStore : GenericDataStore<Byte>
{
}
public class DoubleDataStore : GenericDataStore<Double>
{
}
public class PObjDataStore : GenericDataStore<PObj> // PObj is another class declared somewhere
{
}

然后,我有一个“经理”类,看起来像:

public class DataManager
{
     /* Here, I want to declare a 2 dim array [,] that holds pointers to the
        data stores. Depending on some other variables, the array may need
        to point to DoubleDataStore, ByteDataStore, etc. The following doesn't work,
        since GenericDataStore must be declared with a generic type: */

        GenericDataStore [,] ManagedDataStores; // Can not compile

        public DataManager() {
           for (int i=0; i<numStores; i++) {
               for (int j=0; j<numCopies; j++) {
                   // objType is a utility function that we have that returns a type
                   if (objType(i,j) == typeof(Byte)) {
                         ManagedDataStores[i,j] = new ByteDataStore();
                   } else if (objType(i,j) == typeof(double)) {
                         ManagedDataStores[i,j] = new DoubleDataStore();
                   }
               }
           }
        }

        void Add(int id, int copyid, Byte data) {
             ManagedDataStores[i,j].Add(data);
        }

}

可能还有其他更好的方法可以做到这一点。本质上,我们希望为不同的对象类型提供不同的数据存储,这些数据存储可以由类管理。我们只希望这个'manager'类暴露给用户(比如API),并且不能直接访问底层类。

提前致谢。

3 个答案:

答案 0 :(得分:1)

我担心这是Generic不会帮助你的那些例子之一。根据定义,您必须在编译时知道泛型类型,而不是运行时。对于运行时类型不一致,您需要以老式的方式进行。

public class DataStore
{
     // UnderlyingDataStore is another class that manages a queue, or a linked list
     private UnderlyingDataStore dataQueue = new UnderlyingDataStore();
     public void addData(object data) { dataQueue.Add(data); }
     public object getLastData() { dataQueue.getLastData(); }
}

这有装箱/拆箱的明显缺点 - 以及需要调用代码才能知道它应该处理什么类型才能进行投射。

但是,您也可以使用the other answer,只要您能够将managedDataStore转换为正确的泛型类型即可。

答案 1 :(得分:0)

如果要创建和初始化双维数组,请使用:

int numStores = 2;
int numCopies = 3;

//GenericDataStore<object>[,] managedDataStores = new GenericDataStore<object>[numStores,numCopies];
 Object[,] managedDataStores = new Object[numStores,numCopies];
for (int i = 0; i < numStores; i++)
{
   for (int j = 0; j < numCopies; j++)
   {
    managedDataStores[i,j] = new GenericDataStore<object>();
   }
}

答案 2 :(得分:0)

我会添加一个接口并明确地实现它以将其隐藏在类用户中:

internal interface GeneralDataStore
{
     void addData(object data);
     object getLastData();
}

public class GenericDataStore<T> : GeneralDataStore
{
     // UnderlyingDataStore is another class that manages a queue, or a linked list
     private UnderlyingDataStore<T> dataQueue = new UnderlyingDataStore<T>();
     public void addData(T data) { dataQueue.Add(data); }
     public T getLastData() { dataQueue.getLastData(); }

     object GeneralDataStore.getLastData() { return getLastData(); }
     void GeneralDataStore.addData(object data) { add((T)data); }
}

GeneralDataStore [,] ManagedDataStores;

这不能给你你想要的东西,因为它是不可能的。但它给你一些类型安全。