stride3d/stride · error · InvalidOperationException

No comparison available or provided for items of this…

Error message

No comparison available or provided for items of this collection.

What it means

GetIndex locates (or computes the insert index for) an item via DefaultCompareFunc. If no comparison function is available (null) when GetIndex is invoked — e.g. the collection was created through a path that skipped comparer resolution — it throws InvalidOperationException instead of silently mis-ordering.

Solutions

  1. Recreate the collection with a valid comparer or ensure T implements IComparable
  2. Pass a comparison function through the constructor overload used by your subclass
  3. Check the initialization path (e.g. deserialization) that produced a comparer-less collection
  4. Call the GetIndex overload that takes an explicit compareFunc when no default is available

Example fix

// before
var idx = col.GetIndex(item, false); // DefaultCompareFunc null
// after
var col = new SortedObservableCollection<MyVm>(Comparer<MyVm>.Create((a, b) => a.Name.CompareTo(b.Name)));
var idx = col.GetIndex(item, false);
Defensive patterns

Strategy: validation

Validate before calling

var safeCol = col.DefaultCompareFunc != null ? col : new SortedObservableCollection<T>(Comparer<T>.Create(cmp));

Try / catch

try { var idx = col.GetIndex(item, false); } catch (InvalidOperationException) { /* comparer missing; rebuild collection with comparer */ }

Prevention

When it happens

Trigger: Calling methods that rely on GetIndex (insert, binary search, index lookup) on a SortedObservableCollection whose DefaultCompareFunc is null — typically via a constructor path that did not resolve a comparer, or after the comparer was cleared.

Common situations: Subclasses that bypass the validating constructor; deserialization rebuilding the collection without a comparer; calling protected sorting helpers on a badly initialized instance.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/13be450e93ce85ad. Report an issue: GitHub.

Appendix: source

Thrown at sources/presentation/Stride.Core.Presentation/Collections/SortedObservableCollection.cs:126

        {
            if (typeof(T).GetInterfaces().Contains(typeof(IComparable<TSearch>)))
                compareFunc = (item1, item2) => ((IComparable<TSearch>)item1!).CompareTo(item2);
            else
                throw new ArgumentNullException(nameof(compareFunc));
        }

        return GetIndex(key, false, compareFunc);
    }

    /// <inheritdoc/>
    public override string ToString()
    {
        return $"{{SortedObservableCollection}} Count = {Count}";
    }

    protected int GetIndex(T item, bool returnInsertIndex)
    {
        if (DefaultCompareFunc is null) throw new InvalidOperationException("No comparison available or provided for items of this collection.");
        return GetIndex(item, returnInsertIndex, DefaultCompareFunc.Invoke);
    }

    protected int GetIndex<TSearch>(TSearch key, bool returnInsertIndex, Func<T, TSearch, int> compareFunc)
    {
        int imin = 0;
        int imax = Count - 1;
        while (imax >= imin)
        {
            int imid = (imin + imax) / 2;

            int comp = compareFunc(this[imid], key);
            if (comp < 0)
                imin = imid + 1;
            else if (comp > 0)
                imax = imid - 1;
            else
                return imid;

View on GitHub (pinned to 96fad776d2)