louthy/language-ext · error · ArgumentException
must be of type Velocity
Error message
must be of type Velocity
What it means
Velocity's explicit CompareTo(object?) throws ArgumentException('must be of type Velocity') when the argument is non-null but not a Velocity. The library follows the standard IComparable pattern: null yields 1, a real Velocity delegates to the typed overload, anything else is a caller bug. Only object/IComparable-typed dispatch paths can reach this throw.
Solutions
- Only compare same-typed values; keep Velocity collections typed as List<Velocity>
- Use the generic CompareTo(Velocity) overload directly
- Type-check with `obj is Velocity` before the non-generic call
- Catch ArgumentException when consuming untyped external data
Example fix
// before
if (((IComparable)v).CompareTo(new TimeSq(1)) > 0) { } // ArgumentException
// after
if (other is Velocity v2)
{
if (v.CompareTo(v2) > 0) { }
} Defensive patterns
Strategy: type-guard
Validate before calling
if (obj is not Velocity) return -1; // or throw, per policy — before calling CompareTo(object)
Type guard
static bool IsVelocity(object? o) => o is Velocity;
Try / catch
try { r = ((IComparable)vel).CompareTo(obj); }
catch (ArgumentException) { r = string.Compare(vel.GetType().Name, obj?.GetType().Name); } Prevention
- Use the typed CompareTo(Velocity) overload whenever possible
- Avoid boxing velocities into object collections
- Use OfType<Velocity>() to sanitize mixed sequences
- Enforce homogeneous typing at collection creation
When it happens
Trigger: Comparing a Velocity against a different unit type (Time, VelocitySq, boxed primitives) via the non-generic CompareTo or through non-generic sort/search APIs (ArrayList.BinarySearch, Array.Sort(object[])).
Common situations: Mixing unit structs in untyped collections; reflection-based comparers; code migrated from object-based collections to unit types without tightening types.
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 Time
- must be of type TimeSq
- must be of type VelocitySq
- The minimum value for
- Ord attribute should have a struct type that derives from…
AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15).
Data as JSON: /api/errors/8d681f5d9793e29a.
Report an issue: GitHub.
Appendix: source
Thrown at LanguageExt.Core/Units of Measure/Velocity.cs:45
public bool Equals(Velocity other) =>
Value.Equals(other.Value);
public bool Equals(Velocity other, double epsilon) =>
Math.Abs(other.Value - Value) < epsilon;
public override bool Equals(object? obj) =>
obj is Velocity velocity && Equals(velocity);
public override int GetHashCode() =>
Value.GetHashCode();
public int CompareTo(object? obj) =>
obj switch
{
null => 1,
Velocity other => CompareTo(other),
_ => throw new ArgumentException($"must be of type {nameof(Velocity)}")
};
public int CompareTo(Velocity other) =>
Value.CompareTo(other.Value);
public Velocity Add(Velocity rhs) =>
new (Value + rhs.Value);
public Velocity Subtract(Velocity rhs) =>
new (Value - rhs.Value);
public Velocity Multiply(double rhs) =>
new (Value * rhs);
public Velocity Divide(double rhs) =>
new (Value / rhs);
public static Velocity operator *(Velocity lhs, double rhs) =>View on GitHub (pinned to 2f0e362824)