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
- Ensure the compared operand is a Length; convert other units explicitly first if a conversion is intended.
- Prefer the generic CompareTo(Length) or LINQ OrderBy(x => x.Value).
- Guard with a pattern match before invoking the object overload.
- 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
- Prefer CompareTo(Length) and LINQ OrderBy over object-based comparison
- Keep Length values in generic collections
- Never compare Length against other unit structs directly
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
- must be of type Area
- must be of type Mass
- Can't create an IterableNE from an empty sequence
- Cannot create an IterableNE from an empty span
- Key doesn't exist in map
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)