You could have a Stack for each type of objects you want to pool. In your case, that would be 3 stacks. Then inside your Pool's Get method, you would have logic to determine which pool should be used to get the proper object. I do it by passing a parameter to the Get method, but it depends on your particular implementation.
public IType Get(int type)
{
switch (type)
{
case 1:
if (pool1.Count == 0)
{
return new MyObject1();
}
else
{
return pool1.Pop();
}
break;
case 2:
if (pool2.Count == 0)
{
return new MyObject2();
}
else
{
return pool2.Pop();
}
break;
case 3:
if (pool3.Count == 0)
{
return new MyObject3();
}
else
{
return pool3.Pop();
}
break;
}
}
In your Free method, you can have an If...Else like this:
public void Free(IType obj)
{
if (obj is MyObject1)
{
if (pool1.Count < MAX_POOL_SIZE)
pool1.Push(obj);
}
else if (obj is MyObject2)
{
if (pool2.Count < MAX_POOL_SIZE)
pool2.Push(obj);
}
else if (obj is MyObject2)
{
if (pool3.Count < MAX_POOL_SIZE)
pool3.Push(obj);
}
}
Ideally, you have control over the class of the objects being pooled. In which case, you would add a properties to them that would explicitly specify their true type, then in your Free method, you would do your logic on that property instead of having to use reflection. That would give you better performance.