Объявление массива базового класса и создание экземпляров унаследованных членов - PullRequest
1 голос
/ 18 февраля 2011

У меня есть класс, определенный с помощью универсального:

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
{
}

Затем у меня есть класс "Manager"это выглядит так:

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 ]

1 голос
/ 18 февраля 2011

Боюсь, что это один из тех случаев, когда Дженерик не поможет вам ни на шаг. По определению вы должны знать универсальный тип во время компиляции, а не во время выполнения. Для индикации безразличия во время выполнения вы должны сделать это старомодным способом.

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(); }
}

Это имеет очевидный недостаток: бокс / распаковка, а также необходимость в вызывающем коде, чтобы знать, с каким типом он должен иметь дело для приведения.

Тем не менее, вы также можете использовать другой ответ , если вы можете преобразовать managedDataStore к правильному универсальному типу.

0 голосов
/ 18 февраля 2011

Я бы добавил интерфейс и реализовал его явно, чтобы скрыть его от пользователей класса:

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;

Это не даст вам того, что вы хотите, так как это невозможно.Но это дает вам некоторую безопасность типов.

0 голосов
/ 18 февраля 2011

Если вы хотите создать и инициализировать двумерный массив, используйте это:

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>();
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...