{"record":{"id":"a37d8299ccf766fe","repo":"EllanJiang/GameFramework","slug":"reference-type-is-not-a-non-abstract-class-type","errorCode":null,"errorMessage":"Reference type is not a non-abstract class type.","messagePattern":"Reference type is not a non-abstract class type\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Base/ReferencePool/ReferencePool.cs","lineNumber":196,"sourceCode":"            InternalCheckReferenceType(referenceType);\n            GetReferenceCollection(referenceType).RemoveAll();\n        }\n\n        private static void InternalCheckReferenceType(Type referenceType)\n        {\n            if (!m_EnableStrictCheck)\n            {\n                return;\n            }\n\n            if (referenceType == null)\n            {\n                throw new GameFrameworkException(\"Reference type is invalid.\");\n            }\n\n            if (!referenceType.IsClass || referenceType.IsAbstract)\n            {\n                throw new GameFrameworkException(\"Reference type is not a non-abstract class type.\");\n            }\n\n            if (!typeof(IReference).IsAssignableFrom(referenceType))\n            {\n                throw new GameFrameworkException(Utility.Text.Format(\"Reference type '{0}' is invalid.\", referenceType.FullName));\n            }\n        }\n\n        private static ReferenceCollection GetReferenceCollection(Type referenceType)\n        {\n            if (referenceType == null)\n            {\n                throw new GameFrameworkException(\"ReferenceType is invalid.\");\n            }\n\n            ReferenceCollection referenceCollection = null;\n            lock (s_ReferenceCollections)\n            {","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Base/ReferencePool/ReferencePool.cs#L178-L214","documentation":"ReferencePool requires every pooled type to be a concrete (non-abstract) class, because the pool must be able to instantiate it with new(). InternalCheckReferenceType rejects interface or abstract types with this message on all entry points (Acquire, Release, Add, Remove, RemoveAll).","triggerScenarios":"Calling ReferencePool.Add<T>, Acquire<T>, or Remove<T> where T is an interface (e.g. IReference itself) or an abstract base class of your reference hierarchy.","commonSituations":"Trying to pre-warm a pool against an interface 'for all implementers' — pooling is per concrete type, not per interface; registering an abstract base in generic pool-initialization loops over a hierarchy.","solutions":["Use only concrete, instantiable classes implementing IReference for all ReferencePool calls.","If you have several implementations, register each concrete type separately (Add<ImplA>(n), Add<ImplB>(n)).","Add a static check or unit test that iterates your registered types and asserts !type.IsAbstract."],"exampleFix":"// before\nReferencePool.Add<IReference>(100); // interface type\n\n// after\nReferencePool.Add<MyConcreteReference>(100); // concrete class implementing IReference","handlingStrategy":"validation","validationCode":"System.Diagnostics.Debug.Assert(\n    typeof(T).IsClass && !typeof(T).IsAbstract,\n    \"ReferencePool requires a concrete class, got: \" + typeof(T).FullName);","typeGuard":"static bool IsConcreteClass(Type t) => t != null && t.IsClass && !t.IsAbstract;","tryCatchPattern":"try { ReferencePool.Add<T>(count); }\ncatch (GameFrameworkException ex) when (ex.Message.Contains(\"non-abstract class\"))\n{\n    // T is an interface or abstract class — switch to each concrete implementation\n}","preventionTips":["Pool concrete classes only; never register interfaces or abstract bases.","Register each implementation of a hierarchy separately if all of them need pooling.","Constrain generic helpers with 'where T : class, IReference, new()' so the compiler enforces concreteness."],"tags":["object-pool","abstract-class","type-validation","reference-pool"],"backgroundTag":"type-mismatch","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"}