{"record":{"id":"d366c2c6c6cc909e","repo":"louthy/language-ext","slug":"must-be-of-type-length","errorCode":null,"errorMessage":"must be of type Length","messagePattern":"must be of type Length","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/Units of Measure/Length.cs","lineNumber":45,"sourceCode":"\n    public bool Equals(Length other) =>\n        Value.Equals(other.Value);\n\n    public bool Equals(Length other, double epsilon) =>\n        Math.Abs(other.Value - Value) < epsilon;\n\n    public override bool Equals(object? obj) =>\n        obj is Length length && Equals(length);\n\n    public override int GetHashCode() =>\n        Value.GetHashCode();\n\n    public int CompareTo(object? obj) =>\n        obj switch\n        {\n            null         => 1,\n            Length other => CompareTo(other),\n            _            => throw new ArgumentException($\"must be of type {nameof(Length)}\")\n        };\n\n    public int CompareTo(Length other) =>\n        Value.CompareTo(other.Value);\n\n    public Length Add(Length rhs) =>\n        new (Value + rhs.Value);\n\n    public Length Subtract(Length rhs) =>\n        new (Value - rhs.Value);\n\n    public Length Multiply(double rhs) =>\n        new (Value * rhs);\n\n    public Length Divide(double rhs) =>\n        new (Value / rhs);\n\n    public static Area operator *(Length lhs, Length rhs) =>","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/Units of Measure/Length.cs#L27-L63","documentation":"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.","triggerScenarios":"areaLengthPattern: length.CompareTo(42), length.CompareTo(someMass), or routing Length values through non-generic sorting/comparer APIs where the argument is typed as object.","commonSituations":"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.","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()."],"exampleFix":"// before\nlist.Sort((x, y) => ((IComparable)x).CompareTo(y)); // throws for non-Length\n// after\nlistOfLengths.Sort((a, b) => a.CompareTo(b));","handlingStrategy":"type-guard","validationCode":"if (obj is null || obj is Length) { /* safe to compare */ }","typeGuard":"static bool IsComparableLength(object? obj) => obj is null or Length;","tryCatchPattern":"try { r = ((IComparable)length).CompareTo(obj); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"must be of type Length\")) { /* handle mismatch */ }","preventionTips":["Prefer CompareTo(Length) and LINQ OrderBy over object-based comparison","Keep Length values in generic collections","Never compare Length against other unit structs directly"],"tags":["argument-exception","units-of-measure","comparison","type-safety"],"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"}