2016-06-22 91 views
1

是否可以創建一個通用對象池來在其中創建新對象? 如果這個對象創建可以接收參數,那麼它會很好。通用對象池

public interface IPoolable 
    { 
     void Dispose(); 
    } 


    public class ObjectPool<T> where T : IPoolable 
    { 
     private List<T> pool; 

     public T Get() 
     { 
      if(pool.count > 0) 
      { 
       return pool.Pop(); 
      } 
      else 
      { 
       return new T(); // <- How to do this properly? 
      } 
     } 
    } 

    public class SomeClass : IPoolable 
    { 
     int id; 

     public SomeClass(int id) 
     { 
      this.id = id; 
     } 

     public void Dispose() 
     { 

     } 
    } 

    public class OtherClass : IPoolable 
    { 
     string name; 
     int id; 

     public OtherClass(string name, int id) 
     { 
      this.name = name; 
      this.id = id; 
     } 

     public void Dispose() 
     { 

     } 
    } 

在某種程度上,它可以這樣使用,如果它可以接收參數。

SomeClass a = myPool.Get(2); 
OtherClass b = myOtherPool.Get("foo", 4); 

或者如果參數不可行,這也可以。

SomeClass a = myPool.Get(); 
a.id = 2; 
OtherClass b = myOtherPool.Get(); 
b.name = "foo"; 
b.id = 4; 
+0

你基本上是在談論一個工廠?這是一種常見的面向對象模式。池可能是它的一個組件,但是,一般來說,實例化一個對象非常快,並且除非在構造函數中需要完成很多對象設置,否則將不必使用池。使其具有通用性的唯一方法是使用反射來實例化對象。 – itsme86

+0

他正在討論如何維護一個已經創建的對象池,並且只在池爲空時才創建一個新實例,就像連接池如何工作而不是通用連接一樣。我同意,對於輕的物體,這有點浪費。 – Kevin

回答

3

可以使用Activator.CreateInstance Method

public static object CreateInstance(
    Type type, 
    params object[] args 
) 

像這樣

return (T)Activator.CreateInstance(typeof(T), id); 

有,但是,沒有辦法來指定一個類型必須提供帶有參數的構造方法;既不在接口聲明中,也不在泛型類型約束中,也不在類繼承中使用。

1

你可以做這樣的事情:

public class ObjectPool<T> 
{ 
    private Queue<T> _pool = new Queue<T>(); 

    private const int _maxObjects = 100; // Set this to whatever 

    public T Get(params object[] parameters) 
    { 
     T obj; 

     if (_pool.Count < 1) 
      obj = (T)Activator.CreateInstance(typeof(T), parameters); 
     else 
      obj = _pool.Dequeue(); 

     return obj; 
    } 

    public void Put(T obj) 
    { 
     if (_pool.Count < _maxObjects) 
      _pool.Enqueue(obj); 
    } 
} 
+0

這樣做。謝謝! – MathiasDG