logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Class ClassVirtualizer

    Editor helper that makes an existing class subclass-friendly by rewriting its eligible public members to public virtual — the missing first step before the Subclass style (or the Class kind) can target a class with no overridable members. The Unity half only locates the script, enumerates the compiled type's patchable members, and confirms with the user; the actual text rewrite lives in the pure VirtualizationEngine, which refuses whole-file rather than ever writing a partial rewrite. Fields, events, indexers, operators, statics and nested types are deliberately out of scope — only plain public and protected methods and properties are patched (protected internal and private protected members are excluded: overriding them across assemblies carries accessibility subtleties the tool does not model).

    Inheritance
    object
    ClassVirtualizer
    Inherited Members
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    Namespace: Serenity.ServiceExtensionCreator.Editor
    Assembly: Serenity.ServiceExtensionCreator.Editor.dll
    Syntax
    public static class ClassVirtualizer

    Fields

    SuppressDialogs

    Test seam: suppresses the refusal/confirmation dialogs exactly like batch mode does, so EditMode tests can drive TryMakeSubclassFriendly(Type, out string) in an interactive editor without a modal dialog blocking the run. Never set outside tests.

    Declaration
    public static bool SuppressDialogs
    Field Value
    Type Description
    bool

    Methods

    CollectPatchableMembers(Type)

    Every member the rewrite targets, from the COMPILED type (so the patch list can never drift from what reflection-based discovery checks): declared-only public instance methods that are neither virtual, static nor special-name (property/event accessors and operators are special-name; constructors and explicit interface implementations never enumerate as public methods), grouped by name into one MemberPatch carrying the overload count — plus non-indexer properties with at least one non-virtual, non-static accessor. Public so tests can pin the enumeration against a fixture type directly (this path never goes through discovery).

    Declaration
    public static IReadOnlyList<MemberPatch> CollectPatchableMembers(Type type)
    Parameters
    Type Name Description
    Type type
    Returns
    Type Description
    IReadOnlyList<MemberPatch>

    HasPatchableMethods(Type)

    True when type declares at least one patchable public instance method — the cheap "could virtualization make this class subclass-eligible" probe DiscoverVirtualizableUserClasses() sweeps with, sharing the exact member predicate CollectPatchableMembers(Type) patches so the two can never drift.

    Declaration
    public static bool HasPatchableMethods(Type type)
    Parameters
    Type Name Description
    Type type
    Returns
    Type Description
    bool

    MakeSelectedClassSubclassFriendly()

    Declaration
    public static void MakeSelectedClassSubclassFriendly()

    TryMakeSubclassFriendly(Type, IReadOnlyList<MemberPatch>, out string)

    The member-selection twin of TryMakeSubclassFriendly(Type, out string): virtualizes only selection instead of every patchable member. The selection must be a subset of CollectPatchableMembers(Type)'s result (matched by name and member shape — a selected method always virtualizes ALL its overloads, since the compiled overload count is what keeps the text rewrite honest) and must contain at least one METHOD — properties alone keep the class ineligible. The confirmation dialog lists exactly the selected members.

    Declaration
    public static bool TryMakeSubclassFriendly(Type type, IReadOnlyList<MemberPatch> selection, out string message)
    Parameters
    Type Name Description
    Type type
    IReadOnlyList<MemberPatch> selection
    string message
    Returns
    Type Description
    bool

    TryMakeSubclassFriendly(Type, out string)

    Enumerates type's patchable members, locates its script, and rewrites them to public virtual after an explicit confirmation listing exactly what changes. The flow is gated on patchable METHODS: subclass eligibility keys on overridable public or protected methods, so a class with none to virtualize is refused (properties are only patched alongside at least one method). Refusals (nothing method-shaped, no unique script, a partial class, conditional compilation, or a source/type mismatch) surface a dialog and write NOTHING. Dialogs are skipped in batch mode (UnityEngine.Application.isBatchMode) and under SuppressDialogs so tests and CLI runs can drive this headlessly. On success the file is rewritten, assets refresh, and every discovery cache is invalidated so the class immediately surfaces as subclassable.

    Declaration
    public static bool TryMakeSubclassFriendly(Type type, out string message)
    Parameters
    Type Name Description
    Type type
    string message
    Returns
    Type Description
    bool

    ValidateMakeSelectedClassSubclassFriendly()

    Declaration
    public static bool ValidateMakeSelectedClassSubclassFriendly()
    Returns
    Type Description
    bool
    In this article
    © 2026 Serenity. All Rights Reserved