What is the purpose of the PooledObject<T> struct?

I recently began working with Unity’s object pooling API, and noticed that implementing the IObjectPool interface is forcing me to implement a method that returns a PooledObject struct. However, this struct doesn’t actually have any accessible members, so what is its use? It’s also not in the Unity documentation (Unity - Scripting API: IObjectPool<T0>), which is strange.

This is what the assembly shows:

using System;
using UnityEngine.Pool;

public struct PooledObject<T> : IDisposable where T : class
{
    private readonly T m_ToReturn;

    private readonly IObjectPool<T> m_Pool;

    internal PooledObject (T value, IObjectPool<T> pool)
    {
        m_ToReturn = value;
        m_Pool = pool;
    }

    void IDisposable.Dispose ()
    {
        m_Pool.Release (m_ToReturn);
    }
}

What is happening with IDisposable.Dispose? I thought C# discourages us from implementing IDisposable on structs.

My best guess is that this is supposed to somehow automatically return objects to their pools if the user forgets to do so, but I couldn’t make this happen in my testing.

IDisposable is for automatic returning of the pooled object once you leave scope. It will only work if used with the using keyword. It’s useful when the code has a lot of branching and returns and you don’t want to have to add a Release in multiple parts, you just put the code inside of a using block instead.

using System.Text;
using UnityEngine;
using UnityEngine.Pool;

public class Example : MonoBehaviour
{
   static ObjectPool<StringBuilder> stringBuilderPool = new ObjectPool<StringBuilder>(
       () => new StringBuilder(),
       (sb) => sb.Clear());

    void Update()
   {
       StringBuilder stringBuilder;

        // When the pooled object is disposed the string builder will be returned back to the pool
       using (stringBuilderPool.Get(out stringBuilder))
       {
           stringBuilder.AppendLine("Some text");
           Debug.Log(stringBuilder.ToString());
       }
   }
}

A struct is fine to use here, it’s only used in scope, should only be used by the using statement. A class would generate garbage which would go against the point of a pooling system.

3 Likes

Thank you!