{"record":{"id":"47a6e734bf809976","repo":"EllanJiang/GameFramework","slug":"release-object-filter-callback-is-invalid","errorCode":null,"errorMessage":"Release object filter callback is invalid.","messagePattern":"Release object filter callback is invalid\\.","errorType":"validation","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs","lineNumber":477,"sourceCode":"            /// <summary>\n            /// 释放对象池中的可释放对象。\n            /// </summary>\n            /// <param name=\"releaseObjectFilterCallback\">释放对象筛选函数。</param>\n            public void Release(ReleaseObjectFilterCallback<T> releaseObjectFilterCallback)\n            {\n                Release(Count - m_Capacity, releaseObjectFilterCallback);\n            }\n\n            /// <summary>\n            /// 释放对象池中的可释放对象。\n            /// </summary>\n            /// <param name=\"toReleaseCount\">尝试释放对象数量。</param>\n            /// <param name=\"releaseObjectFilterCallback\">释放对象筛选函数。</param>\n            public void Release(int toReleaseCount, ReleaseObjectFilterCallback<T> releaseObjectFilterCallback)\n            {\n                if (releaseObjectFilterCallback == null)\n                {\n                    throw new GameFrameworkException(\"Release object filter callback is invalid.\");\n                }\n\n                if (toReleaseCount < 0)\n                {\n                    toReleaseCount = 0;\n                }\n\n                DateTime expireTime = DateTime.MinValue;\n                if (m_ExpireTime < float.MaxValue)\n                {\n                    expireTime = DateTime.UtcNow.AddSeconds(-m_ExpireTime);\n                }\n\n                m_AutoReleaseTime = 0f;\n                GetCanReleaseObjects(m_CachedCanReleaseObjects);\n                List<T> toReleaseObjects = releaseObjectFilterCallback(m_CachedCanReleaseObjects, toReleaseCount, expireTime);\n                if (toReleaseObjects == null || toReleaseObjects.Count <= 0)\n                {","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/ObjectPool/ObjectPoolManager.ObjectPool.cs#L459-L495","documentation":"ObjectPool<T>.Release(int toReleaseCount, ReleaseObjectFilterCallback<T>) requires a filter callback to decide which objects may be released. Passing a null delegate is rejected with this GameFrameworkException before any release logic runs.","triggerScenarios":"Calling Release(count, null); a filter delegate variable that was never assigned or was cleared; invoking the count-based overload intending to use the parameterless default-filter path.","commonSituations":"Refactoring from Release() (no-arg) or Release(count) to the filtered overload and forgetting the callback; conditional callback assignment that left it null.","solutions":["Pass a real filter, e.g. (obj) => true to release any candidate.","Use the parameterless Release() or Release(int) overloads when no custom filtering is needed.","Ensure the callback field is initialized before the release call."],"exampleFix":"// before\npool.Release(5, null);\n// after\npool.Release(5, internalObject => internalObject.Priority < 10);","handlingStrategy":"validation","validationCode":"if (releaseObjectFilterCallback != null)\n{\n    pool.Release(toReleaseCount, releaseObjectFilterCallback);\n}\nelse\n{\n    pool.Release(toReleaseCount); // default behavior\n}","typeGuard":null,"tryCatchPattern":"try { pool.Release(count, filter); }\ncatch (GameFrameworkException) { /* filter was null; fall back to pool.Release(count) */ }","preventionTips":["Initialize filter delegates at declaration time.","Use Release() or Release(int) overloads when custom filtering is not needed.","Default to (obj) => true if a 'release anything eligible' semantic is intended."],"tags":["gameframework","objectpool","null-argument","callback"],"backgroundTag":"null-argument","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}