louthy/language-ext · error · ArgumentException

must be of type VelocitySq

Error message

must be of type VelocitySq

What it means

VelocitySq's explicit CompareTo(object?) throws ArgumentException('must be of type VelocitySq') for any non-null argument that is not a VelocitySq. This enforces the IComparable non-generic contract that comparing across types is an error rather than returning an arbitrary ordering. It can only trigger via object-typed compare paths, since the generic overload is type-safe.

Solutions

  1. Keep collections and comparers generic (IComparer<VelocitySq>, List<VelocitySq>.Sort)
  2. Pre-check the argument with `is VelocitySq` before non-generic comparison
  3. Normalize incoming data to VelocitySq at ingestion time
  4. Catch ArgumentException around any remaining object-typed compare paths

Example fix

// before
int r = ((IComparable)vs).CompareTo(new Velocity(5)); // ArgumentException
// after
int r = other is VelocitySq o ? vs.CompareTo(o) : throw new ArgumentException("not a VelocitySq");
Defensive patterns

Strategy: type-guard

Validate before calling

if (obj is not VelocitySq) throw new ArgumentException("expected VelocitySq");

Type guard

static bool IsVelocitySq(object? o) => o is VelocitySq;

Try / catch

try { r = ((IComparable)velSq).CompareTo(obj); }
catch (ArgumentException ex) { throw new InvalidOperationException("cross-type compare", ex); }

Prevention

When it happens

Trigger: Invoking CompareTo((object)someNonVelocitySq) or sorting/searching non-generic collections (ArrayList, object arrays) that contain a VelocitySq among values of other types.

Common situations: Untyped legacy collections mixing unit-of-measure structs; dynamic/reflection comparisons; data-binding frameworks that box values before comparing.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15). Data as JSON: /api/errors/728c5ca850bc429b. Report an issue: GitHub.

Appendix: source

Thrown at LanguageExt.Core/Units of Measure/VelocitySq.cs:39

    public bool Equals(VelocitySq other) =>
        Value.Equals(other.Value);

    public bool Equals(VelocitySq other, double epsilon) =>
        Math.Abs(other.Value - Value) < epsilon;

    public override bool Equals(object? obj) =>
        obj is VelocitySq sq && Equals(sq);

    public override int GetHashCode() =>
        Value.GetHashCode();

    public int CompareTo(object? obj) =>
        obj switch
        {
            null             => 1,
            VelocitySq other => CompareTo(other),
            _                => throw new ArgumentException($"must be of type {nameof(VelocitySq)}")
        };

    public int CompareTo(VelocitySq other) =>
        Value.CompareTo(other.Value);

    public VelocitySq Add(VelocitySq rhs) =>
        new (Value + rhs.Value);

    public VelocitySq Subtract(VelocitySq rhs) =>
        new (Value - rhs.Value);

    public VelocitySq Multiply(double rhs) =>
        new (Value * rhs);

    public VelocitySq Divide(double rhs) =>
        new (Value / rhs);

    public static VelocitySq operator *(VelocitySq lhs, double rhs) =>

View on GitHub (pinned to 2f0e362824)