2011-12-16 48 views
1

短版:一個對象池包含不同的派生類

我怎麼會去創建一個可以存儲不同類型的類都是從同一個基類派生的對象池?
有關預期用法的示例,請參見下文。


龍版本:

我有一個類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); 
} 
+0

而你所面對的實際問題? –

+0

如果對象池包含BaseClass的列表,我如何找到我想要的DerivedClass實例?迭代列表將太慢。 –

+0

爲什麼慢?你在想多少個實例?你的問題的答案在很大程度上取決於'EntityTemplate'和'MagicComponentPool'的內部運作。你並不認爲你是如何識別單個組件的。按類型?通過某種類型的ID? –

回答

1

我會用一本字典。

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); 
      } 
     } 
相關問題