Загрузка полиморфных объектов - нужен шаблон - PullRequest
0 голосов
/ 03 декабря 2009

Мне нужен красивый подход для загрузки полиморического объекта

У меня есть базовый класс и несколько производных классов, о которых база не знает. Единственная вещь базовый класс знает, что это тип enum, который определяет, какой это реальный класс.

class Order
{
 OrderType Type;

 bool Load(string filename)
 {
   // load Type
 }
}

class LimitOrder : Order
{

 // some data
 bool Load(string filename)
 {
   // load some data
 }
}

Мне нужно написать метод Load для базового класса Order, который бы правильно создавал соответствующий производный класс. Я ищу хороший образец.

Ответы [ 3 ]

2 голосов
/ 04 декабря 2009

Самый простой способ - использовать встроенный двоичный сериализатор .Net

 IFormatter formatter = new BinaryFormatter();
 Stream stream = new FileStream(filename, FileMode.Create, FileAccess.Write,     FileShare.None);
 formatter.Serialize(stream, obj);

И поместите этот код в своего рода OrderFactory

class OrderFactory
{
   public static Order Load(string filename) {...}
   public static void Save(string filename, Order order) {...}
}
1 голос
/ 04 декабря 2009

Если вы не хотите использовать встроенные сериализаторы .NET, вам нужен какой-то фабричный метод . Вы можете поместить его в отдельный объект фабрики или создать статическую функцию в базовом классе, например:

class Order
{
    public static Order CreateOrder(string filename)
    {
         Stream stream = new FileStream(filename);
         string typeinfo = stream.ReadLine();
         Type t=null;
         if(typeinfo=="LimitOrder")  // this can be improved by using "GetType"
            t=typeof(LimitOrder);
         else if(typeinfo==/* what ever your types are*/
            t= //...
         ConstructorInfo consInfo = t.GetConstructor(new Type[0]);
         Order o= (Order)consInfo.Invoke(new object[0]);
         o.Load(stream);
         stream.Close();
         return o;
    }
}

Чтобы это работало, каждый подкласс Order должен иметь конструктор с 0 параметрами и виртуальный метод Load с параметром stream. И первая строка в вашем файле должна быть typeinfo.

1 голос
/ 04 декабря 2009

Поскольку у вас есть это требование:

У меня есть базовый класс и несколько производных классов, о которых база не знает. Единственное, что знает базовый класс, это Type enum, который определяет, какой это реальный класс.

Чтобы выполнить это, ваши производные классы должны будут предоставить некоторую форму регистрации в базовом классе. Один из подходов может состоять в том, чтобы иметь статический Dictionary<MyTypeEnum,Func<Order>>, определенный в базовом классе, и позволить подклассам регистрироваться в базовом классе для динамического добавления определенной функции создания для их типа в базовый класс. Таким образом, когда файл анализируется, базовый класс может просто вызвать соответствующую функцию для создания производного типа.

...