{"record":{"id":"8d681f5d9793e29a","repo":"louthy/language-ext","slug":"must-be-of-type-velocity","errorCode":null,"errorMessage":"must be of type Velocity","messagePattern":"must be of type Velocity","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/Units of Measure/Velocity.cs","lineNumber":45,"sourceCode":"\n    public bool Equals(Velocity other) =>\n        Value.Equals(other.Value);\n\n    public bool Equals(Velocity other, double epsilon) =>\n        Math.Abs(other.Value - Value) < epsilon;\n\n    public override bool Equals(object? obj) =>\n        obj is Velocity velocity && Equals(velocity);\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            null           => 1,\n            Velocity other => CompareTo(other),\n            _              => throw new ArgumentException($\"must be of type {nameof(Velocity)}\")\n        };\n\n    public int CompareTo(Velocity other) =>\n        Value.CompareTo(other.Value);\n\n    public Velocity Add(Velocity rhs) =>\n        new (Value + rhs.Value);\n\n    public Velocity Subtract(Velocity rhs) =>\n        new (Value - rhs.Value);\n\n    public Velocity Multiply(double rhs) =>\n        new (Value * rhs);\n\n    public Velocity Divide(double rhs) =>\n        new (Value / rhs);\n\n    public static Velocity operator *(Velocity lhs, double rhs) =>","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/Units of Measure/Velocity.cs#L27-L63","documentation":"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.","triggerScenarios":"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[])).","commonSituations":"Mixing unit structs in untyped collections; reflection-based comparers; code migrated from object-based collections to unit types without tightening types.","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"],"exampleFix":"// before\nif (((IComparable)v).CompareTo(new TimeSq(1)) > 0) { } // ArgumentException\n// after\nif (other is Velocity v2)\n{\n    if (v.CompareTo(v2) > 0) { }\n}","handlingStrategy":"type-guard","validationCode":"if (obj is not Velocity) return -1; // or throw, per policy — before calling CompareTo(object)","typeGuard":"static bool IsVelocity(object? o) => o is Velocity;","tryCatchPattern":"try { r = ((IComparable)vel).CompareTo(obj); }\ncatch (ArgumentException) { r = string.Compare(vel.GetType().Name, obj?.GetType().Name); }","preventionTips":["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"],"tags":["csharp","languageext","icomparable","argument"],"backgroundTag":"type-mismatch","analyzedSha":"2f0e3628242889774d4141960a35671a0280051f","analyzedAt":"2026-09-15T03:31:55.716Z","contentChangedAt":"2026-09-15T03:31:55.716Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}