louthy/language-ext · error · ArgumentException
must be of type Time
Error message
must be of type Time
What it means
Time's explicit IComparable.CompareTo(object?) throws ArgumentException('must be of type Time') when passed a non-null object that is not a Time. This is the standard non-generic IComparable contract: null compares as 'greater than nothing' (returns 1), same type delegates to CompareTo(Time), anything else is rejected. The non-generic overload is only reached through APIs typed as object or IComparable.
Solutions
- Ensure all compared values are Time instances before non-generic comparison
- Prefer the generic IComparable<Time>/sort overloads (List<Time>.Sort) so type mismatches cannot occur
- Check `obj is Time` before calling the non-generic CompareTo
- Catch ArgumentException only at legacy-collection boundaries
Example fix
// before
object[] xs = { new Time(1), new TimeSq(2) };
Array.Sort(xs); // ArgumentException: must be of type Time
// after
var xs2 = new List<Time> { new Time(1), new Time(2) };
xs2.Sort(); Defensive patterns
Strategy: type-guard
Validate before calling
if (obj is not Time) throw new ArgumentException($"expected Time, got {obj?.GetType().Name}"); Type guard
static bool IsTime(object? o) => o is Time;
Try / catch
try { r = ((IComparable)time).CompareTo(obj); }
catch (ArgumentException) { r = -1; /* or handle type mismatch explicitly */ } Prevention
- Use List<Time>.Sort / generic IComparable<Time> instead of object-based APIs
- Avoid ArrayList and object[] for typed unit values
- Check `is Time` before non-generic comparison
- Keep unit types out of heterogeneous untyped collections
When it happens
Trigger: Passing a non-Time object (boxed value, different unit type like Velocity, string) to a non-generic sort/compare path such as ArrayList.BinarySearch, Array.Sort(object[]), or CompareTo((object)other) where the value is not a Time.
Common situations: Mixing unit types in legacy non-generic collections; reflection-based comparison code; sorting heterogeneous object arrays that were assumed homogeneous; refactor that changed an element type without updating non-generic sort calls.
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 TimeSq
- must be of type Velocity
- 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/c1234c2c88b35725.
Report an issue: GitHub.
Appendix: source
Thrown at LanguageExt.Core/Units of Measure/Time.cs:45
public bool Equals(Time other) =>
Value.Equals(other.Value);
public bool Equals(Time other, double epsilon) =>
Math.Abs(other.Value - Value) < epsilon;
public override bool Equals(object? obj) =>
obj is Time time && Equals(time);
public override int GetHashCode() =>
Value.GetHashCode();
public int CompareTo(object? obj) =>
obj switch
{
null => 1,
Time other => CompareTo(other),
_ => throw new ArgumentException($"must be of type {nameof(Time)}")
};
public int CompareTo(Time other) =>
Value.CompareTo(other.Value);
public Time Add(Time rhs) =>
new (Value + rhs.Value);
public Time Subtract(Time rhs) =>
new (Value - rhs.Value);
public Time Multiply(double rhs) =>
new (Value * rhs);
public Time Divide(double rhs) =>
new (Value / rhs);
public static Time operator *(Time lhs, double rhs) =>View on GitHub (pinned to 2f0e362824)