{"record":{"id":"1d5bef9fbb951bb3","repo":"louthy/language-ext","slug":"must-be-of-type-mass","errorCode":null,"errorMessage":"must be of type Mass","messagePattern":"must be of type Mass","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/Units of Measure/Mass.cs","lineNumber":21,"sourceCode":"namespace LanguageExt;\n\npublic readonly struct Mass : \n    IComparable<Mass>, \n    IEquatable<Mass>, \n    IComparable\n{\n    readonly double Value;\n\n    internal Mass(double value) =>\n        Value = value;\n\n    public override string ToString() =>\n        Kilograms + \" kg\";\n\n    public int CompareTo(object? obj) =>\n        obj is null         ? 1\n        : obj is Mass other ? CompareTo(other)\n                              : throw new ArgumentException($\"must be of type {nameof(Mass)}\");\n\n    public int CompareTo(Mass other) =>\n        Kilograms.CompareTo(other.Kilograms);\n\n    public bool Equals(Mass other) =>\n        Kilograms.Equals(other.Kilograms);\n\n    public bool Equals(Mass other, double epsilon) =>\n        Math.Abs(other.Kilograms - Kilograms) < epsilon;\n\n    public override bool Equals(object?  obj) =>\n        obj is Mass m && Equals(m);\n\n    public override int GetHashCode() =>\n        Kilograms.GetHashCode();\n\n    public Mass Add(Mass rhs) =>\n        new (Kilograms + rhs.Kilograms);","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/Units of Measure/Mass.cs#L3-L39","documentation":"Mass.CompareTo(object?) throws ArgumentException \"must be of type Mass\" when given a non-null object that is not a Mass. Mass implements IComparable by checking `obj is Mass`; anything else fails. This is a runtime guard for the non-generic IComparable contract, which cannot be enforced at compile time.","triggerScenarios":"mass.CompareTo(\"3 kg\"), mass.CompareTo(kilogramsAsDouble), or non-generic sort/comparer paths delivering boxed non-Mass values to CompareTo(object).","commonSituations":"Parsing raw config/DB strings into weights but forgetting to construct a Mass; non-generic collections storing mixed types; comparing Mass against other LanguageExt unit structs.","solutions":["Construct a Mass from raw values first (e.g. Mass from kilograms) and compare Mass to Mass.","Use the generic CompareTo(Mass) overload or OrderBy(m => m.Kilograms).","Add an `is Mass` check before the comparison and handle mismatches explicitly.","Use generic collections so the typed comparer is invoked."],"exampleFix":"// before\nif (((IComparable)mass).CompareTo(rawKg) > 0) ... // ArgumentException\n// after\nvar other = new Mass(Convert.ToDouble(rawKg));\nif (mass.CompareTo(other) > 0) ...","handlingStrategy":"type-guard","validationCode":"if (obj is null || obj is Mass) { /* safe to compare */ }","typeGuard":"static bool IsComparableMass(object? obj) => obj is null or Mass;","tryCatchPattern":"try { r = ((IComparable)mass).CompareTo(obj); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"must be of type Mass\")) { /* handle mismatch */ }","preventionTips":["Parse raw weights into Mass before comparing","Use the generic CompareTo(Mass) overload","Guard with `is Mass` when input types are dynamic"],"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"}