louthy/language-ext · error · ArgumentException

must be of type Length

Error message

must be of type Length

What it means

Length.CompareTo(object?) throws ArgumentException "must be of type Length" when the object argument is non-null and not a Length. Like the other unit-of-measure structs, Length only supports comparisons against its own type; the non-generic IComparable overload guards this at runtime. Comparing a Length to any other type (including other units) is a programming error.

Solutions

  1. Ensure the compared operand is a Length; convert other units explicitly first if a conversion is intended.
  2. Prefer the generic CompareTo(Length) or LINQ OrderBy(x => x.Value).
  3. Guard with a pattern match before invoking the object overload.
  4. Replace non-generic collection sorting with generic List<Length>.Sort().

Example fix

// before
list.Sort((x, y) => ((IComparable)x).CompareTo(y)); // throws for non-Length
// after
listOfLengths.Sort((a, b) => a.CompareTo(b));
Defensive patterns

Strategy: type-guard

Validate before calling

if (obj is null || obj is Length) { /* safe to compare */ }

Type guard

static bool IsComparableLength(object? obj) => obj is null or Length;

Try / catch

try { r = ((IComparable)length).CompareTo(obj); }
catch (ArgumentException ex) when (ex.Message.Contains("must be of type Length")) { /* handle mismatch */ }

Prevention

When it happens

Trigger: areaLengthPattern: length.CompareTo(42), length.CompareTo(someMass), or routing Length values through non-generic sorting/comparer APIs where the argument is typed as object.

Common situations: Using ArrayList or non-generic IComparer with mixed boxed values; reflection-driven code comparing arbitrary objects; confusing Length with other LanguageExt unit structs that have identical-looking APIs.

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/d366c2c6c6cc909e. Report an issue: GitHub.

Appendix: source

Thrown at LanguageExt.Core/Units of Measure/Length.cs:45

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

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

    public override bool Equals(object? obj) =>
        obj is Length length && Equals(length);

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

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

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

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

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

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

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

    public static Area operator *(Length lhs, Length rhs) =>

View on GitHub (pinned to 2f0e362824)