egametang/ET · error · NotSupportedException

无法为类型 {type.FullName} 生成稳定排序键

Error message

无法为类型 {type.FullName} 生成稳定排序键

What it means

Thrown when the emitter needs a stable string sort key for a value (used to produce deterministic output ordering) but the value's type cannot be formatted as an inline literal by TryFormatInlineValue. Only primitive/inline-formattable types yield a stable key; anything else is rejected so ordering never becomes non-deterministic.

Source

Thrown at Packages/cn.etetet.config/Scripts/Model/Share/CSharpObjectCodeEmitter.cs:559

            info = null;
            return false;
        }

        private string GetStableOrderKey(object value)
        {
            if (value == null)
            {
                return string.Empty;
            }

            Type type = value.GetType();
            if (TryFormatInlineValue(type, value, out string inlineValue))
            {
                return inlineValue;
            }

            throw new NotSupportedException($"无法为类型 {type.FullName} 生成稳定排序键");
        }

        private bool TryFormatInlineValue(Type type, object value, out string code)
        {
            code = null;

            if (value == null)
            {
                code = "null";
                return true;
            }

            Type underlyingType = Nullable.GetUnderlyingType(type);
            if (underlyingType != null)
            {
                return this.TryFormatInlineValue(underlyingType, value, out code);
            }

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Use an inline-formattable type (string, numeric primitive, enum, or a type already handled by TryFormatInlineValue) as the sort key.
  2. Add a formatter branch in TryFormatInlineValue for the new type if it has a stable literal form.
  3. Wrap the value in a comparable surrogate key (e.g. an int id) and sort by that instead.

Example fix

// before
// collection keyed/sorted by a custom struct
// after
// sort by a primitive id the emitter can format inline
Defensive patterns

Strategy: validation

Validate before calling

// only use inline-formattable types as sort keys
static bool IsInlineFormattable(Type t) =>
    t.IsPrimitive || t == typeof(string) || t == typeof(decimal) || t.IsEnum;

Prevention

When it happens

Trigger: Passing a value of an unsupported type (custom struct/class, decimal in some paths, enum-with-custom-format, or any non-inline type) into a context where the emitter must derive a sort key (e.g. ordering dictionary keys / collection elements for stable emission).

Common situations: A config collection contains a custom value type used as a sort key; a new member type is introduced that the emitter's inline formatter does not recognize.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/59116bb87ac54dfc. Report an issue: GitHub.