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

Короткая версия:

Как мне создать пул объектов, в котором можно хранить классы разных типов, все производные от одного базового класса?
Ниже приведен пример ожидаемого использования.


Длинная версия:

У меня есть класс BaseComponent, со многими производными классами, например, Child1Component, Child2Component.

У меня также есть другой объект, представляющий коллекцию этих компонентов, в свойствах которых установлены конкретные значения. Я называю это EntityTemplate, поскольку сущность определяется набором компонентов и их значений.

Я хочу создать сущности на основе компонентов сущностей. Чтобы сделать это в настоящее время, я получаю соответствующий EntityTemplate, перебираю его различные компоненты и вызываю метод Clone, который я определил для каждого дочернего класса. У меня также есть определенный метод Copy, который может быть полезен.

Когда срок действия сущности истекает, я хотел бы добавить ее компоненты в пул объектов, затем, когда мне в следующий раз понадобится создать сущность, я получу шаблон сущности, и для каждого компонента я получу один и тот же тип. пула и установите его свойства равными свойствам в EntityTemplate, что-то вроде ниже:

// What i want to do
var entityTemplate = GetTemplate("UniqueString");
var MyActualEntity = new Entity();

foreach(var componentTemplate in entityTemplate)
{
    var actualComponent = MagicComponentPool
                              .GetComponentSameTypeAsParam(componentTemplate);
    actualComponent.CopyFrom(componentTemplate);

    MyActualEntity.Components.Add(actualComponent);
}

1 Ответ

1 голос
/ 16 декабря 2011

Я бы использовал словарь.

Dictionary<Type, BaseComponent> dictionary = new Dictionary<Type, BaseComponent>();

вставьте оригинальные компоненты так:

dictionary.Add(component.GetType(), component);

и получить их по типу.

BaseComponent component = dictionary[componentTemplate.GetType()];

Сложность извлечения объектов из словарей постоянна независимо от количества объектов в словаре и равна стоимости вычисления хэша ключа.

Однако я не уверен, применимо ли это для вашей цели, но, поскольку вы все равно копируете объекты, почему бы просто не клонировать компоненты из шаблона или даже клонировать весь шаблон.

Вот вам общий метод Clone: ​​

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

        public static T Clone<T>(T o)
        {
            byte[] bytes = SerializeBinary(o);
            return DeserializeBinary<T>(bytes);
        }

        public static byte[] SerializeBinary(object o)
        {
            if (o == null) return null;
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                bf.Serialize(ms, o);
                return ms.GetBuffer();
            }
        }

        public static T DeserializeBinary<T>(byte[] bytes)
        {
            if (bytes == null) return default(T);
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream(bytes))
            {
                return (T) bf.Deserialize(ms);
            }
        }
...