using System.Collections.Concurrent;
public static void Main()
var pool = new ObjectPool<string>(() => "", maxSize: 2);
using (var obj = pool.Get())
int hashCode = obj.Do(e => e.GetHashCode());
public class ObjectPool<T>
private readonly ConcurrentBag<T> m_objects = new ConcurrentBag<T>();
private readonly Func<T> m_objectGenerator;
private int m_counter = 0;
private readonly int m_maxSize;
public ObjectPool(Func<T> objectGenerator, int maxSize)
m_objectGenerator = objectGenerator ?? throw new ArgumentNullException(nameof(objectGenerator));
if (m_objects.TryTake(out T item))
T obj = m_objectGenerator();
public PoolObject<T> Get() => new PoolObject<T>(this, GetImpl());
public void PutObject(T item)
if (m_counter < m_maxSize)
public sealed class PoolObject<T> : IDisposable
private ObjectPool<T> m_objectPool;
public PoolObject(ObjectPool<T> pool, T value)
void IDisposable.Dispose()
m_objectPool.PutObject(m_value);
public void Do(Action<T> action)
public TResult Do<TResult>(Func<T, TResult> action)