一个对象池包含不同的派生类

发布于 2024-12-21 16:28:08 字数 980 浏览 1 评论 0原文

简短版本:

我将如何创建一个对象池来存储所有派生自同一基类的不同类型的类?
请参阅下面的预期用法示例。


长版本:

我有一个类BaseComponent,其中有许多派生类,例如Child1ComponentChild2Component

我还有另一个对象,它表示这些组件的集合,其属性设置为特定值。我将其称为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);
}

Short version:

How would i go about creating an object pool that can store classes of different types all derived from the same base class?
See below for an example of expected usage.


Long version:

I have a class BaseComponent, with many derived classes e.g. Child1Component, Child2Component.

I also have another object that represents a collection of these components, with their properties set to specific values. I call this an EntityTemplate, since an entity is defined by the set of components and their values.

I want to create entities based on entity components. To do this currently i get the appropriate EntityTemplate, loop through it's different components and call a Clone method I've defined on each child class. I also have a Copy method defined there too, which might be useful.

When an entity expires i'd like to add its components to an object pool, then when i next need to create an entity i'd get the entity template and for each component i'd get one of the same type out of the pool and set it's properties equal to the one in the EntityTemplate, something like below:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浅听莫相离 2024-12-28 16:28:08

我会用字典。

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

像这样放入原始组件:

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

并按类型检索它们。

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

无论字典中有多少对象,从字典中检索对象的复杂性都是恒定的,并且等于计算键的哈希值的成本。

但是,我不确定这是否适用于您的目的,但是当您无论如何复制对象时,为什么不直接从模板克隆组件,甚至克隆整个模板。

这是一个适合您的通用克隆方法:

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

I would use a dictionary.

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

put the original components in like this:

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

and retrieve them by type.

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

Complexity of retrieving objects from dictionaries is constant no matter how many objects there’s in the dictionary and is equal to the cost of calculating the hash of the key.

However, I’m not sure if that is applicable for your purpose, but as you are copying the objects anyway, why not just clone the components from the template or even clone the whole template.

Here’s a generic Clone method for you:

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);
            }
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文