public DefaultObjectPool(IPooledObjectPolicy <T> policy, int maximumRetained)
        {
            _policy          = policy ?? throw new ArgumentNullException(nameof(policy));
            _fastPolicy      = policy as PooledObjectPolicy <T>;
            _isDefaultPolicy = IsDefaultPolicy();

            // -1 due to _firstItem
            _items = new ObjectWrapper[maximumRetained - 1];

            bool IsDefaultPolicy()
            {
                var type = policy.GetType();

                return(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(DefaultPooledObjectPolicy <>));
            }
        }
        /// <summary>
        /// Creates an instance of <see cref="Microsoft.Extensions.ObjectPool.DefaultObjectPool{T}"/>.
        /// </summary>
        /// <param name="policy">The pooling policy to use.</param>
        /// <param name="poolSize">The maximum number of objects to retain in the pool.</param>
        public DefaultObjectPool(IPooledObjectPolicy <T> policy, int poolSize)
        {
            _policy          = policy ?? throw new ArgumentNullException(nameof(policy));
            PoolSize         = poolSize;
            _fastPolicy      = policy as PooledObjectPolicy <T>;
            _isDefaultPolicy = IsDefaultPolicy();

            _items = Enumerable.Range(0, poolSize).Select(i => new ObjectWrapper <T>()
            {
                Element = _fastPolicy.OptimisticObjectCreation ? Create() : null, Index = i                                                                        /*, CheckOut = DateTime.MinValue*/
            }).ToArray();

            bool IsDefaultPolicy()
            {
                var type = policy.GetType();

                return(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(DefaultPooledObjectPolicy <>));
            }
        }