2012-02-10 66 views
1

我正在嘗試創建一個對象池,其中包含不同類型的對象。如何創建不同類型的對象池?

是否有可能,如果我傳遞一個字符串作爲ps參數給RetriveFunction(); 它應該rturn一個新的對象的字符串類型或從池中獲取?

字符串將包含類型的名稱。

例如;

Object RetriveFromPool(string typename) 
    { 
      if()//object does not present 
      { 
       //return new object of typename 
      } 
      else 
      { 
       //feth it from pool 
      } 
    } 

它有可能嗎?

回答

2

是的,這是可能的。字典是存儲鍵值對與O(1)查找一個方便的方法和Activator是能夠實例化僅在運行時已知的類型:

private IDictionary<string, object> _objectPool; 
object RetriveFromPool(string typeName) 
{  
    if(_objectPool.ContainsKey(typeName)) 
    { 
     return _objectPool[typename]; // return from the pool 
    } 
    return Activator.CreateInstance(Type.GetType(typeName)); // Try to create a new object using the default constructor 
} 

作爲然而替代(確保編譯時間類型檢查)你不妨使用泛型來實現這一目標:

private IDictionary<Type, object> _objectPool; 
public T RetrieveFromPool<T>() where T : new() 
{ 
    Type type = typeof(T); 
    return _objectPool.ContainsKey(type) ? (T)_objectPool[type] : new T(); 
} 

// Update - add a couple of templates for add methods: 

public void AddToPool<T>() where T : new 
{ 
    _objectPool[typeof(T)] = new T(); 
} 

public void AddToPool<T>(T poolObject) where T : new 
{ 
    _objectPool[typeof(T)] = poolObject; 
} 
+0

是否可以避免反射? – 2012-02-10 13:31:32

+0

@NIleshLanke查看更新。 – 2012-02-10 13:34:20

+0

@ rich.okelly補償你,你一直在竊取我的想法!我們正在同一頁面上思考。儘管如此,你在第一個樣本中有一個錯誤。你永遠不會存儲新實例化的對象。實際上,第二個也一樣。 – Zenexer 2012-02-10 13:35:47

0

如果你的類型是在編譯時已知的,你將與仿製藥更好:

IDictionary<Type, object> Pool = new Dictionary<Type, object>(); 

T RetrieveFromPool<T>() 
    where T : new() 
{ 
    if (Pool.ContainsKey(typeof(T))) 
    { 
     return Pool[typeof(T)]; 
    } 

    return Pool[typeof(T)] = new T(); 
} 

這是使用我可以設計的字符串/反射最安全的方式:

IDictionary<string, object> Pool = new Dictionary<string, object>(); 

object RetrieveFromPool(string typeName) 
{ 
    if (Pool.ContainsKey(typeName)) 
    { 
     return Pool[typeName]; 
    } 

    Type type = Type.GetType(typeName); 
    if (type == null) 
    { 
     return null; 
    } 

    ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes); 
    if (ctor == null) 
    { 
     return null; 
    } 

    object obj = ctor.Invoke(new object[0]); 
    Pool[typeName] = obj; 
    return obj; 
}