{"record":{"id":"6b9d41a6102b346f","repo":"louthy/language-ext","slug":"don-t-use-equals-use-either-recordtype-a-equality-or","errorCode":null,"errorMessage":"Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped","messagePattern":"Don't use Equals - use either RecordType<A>\\.Equality or RecordType<A>\\.EqualityTyped","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"LanguageExt.Core/DataTypes/Record/RecordType.cs","lineNumber":50,"sourceCode":"\n    /// <summary>\n    /// General ToString function\n    /// </summary>\n    public new static Func<A, string> ToString => RecordTypeToString<A>.ToString;\n\n    /// <summary>\n    /// De-serialise an A\n    /// </summary>\n    public static Action<A, SerializationInfo> SetObjectData => RecordTypeSetObjectData<A>.SetObjectData;\n\n    /// <summary>\n    /// Serialise an A\n    /// </summary>\n    public static Action<A, SerializationInfo> GetObjectData => RecordTypeGetObjectData<A>.GetObjectData;\n\n    [Obsolete(\"Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped\")]\n    public new static bool Equals(object objA, object objB) => \n        throw new InvalidOperationException(\"Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped\");\n}\n\ninternal static class RecordTypeIncludeBase<A>\n{\n    internal static readonly bool IncludeBase;\n    \n    static RecordTypeIncludeBase() =>\n        IncludeBase = !typeof(A).CustomAttributes\n                                .AsIterable() \n                                .Exists(a => a.AttributeType.Name == nameof(IgnoreBaseAttribute));\n}\n\ninternal static class RecordTypeHash<A>\n{\n    internal static readonly Func<A, int> Hash;\n    \n    static RecordTypeHash() => \n        Hash = IL.GetHashCode<A>(RecordTypeIncludeBase<A>.IncludeBase);","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/louthy/language-ext/blob/2f0e3628242889774d4141960a35671a0280051f/LanguageExt.Core/DataTypes/Record/RecordType.cs#L32-L68","documentation":"RecordType<A>.Equals(object, object) is explicitly obsoleted and unconditionally throws InvalidOperationException. Record equality in LanguageExt is performed via the Equality/EqualityTyped delegates, so this shadowed Object.Equals overload exists only to fail loudly at runtime (and warn at compile time via [Obsolete]).","triggerScenarios":"Calling RecordType<A>.Equals(objA, objB) directly, e.g. translating object.Equals(a, b) code to RecordType.Equals without switching to RecordType<A>.Equality(a, b).","commonSituations":"Refactoring from record class helpers to RecordType-based value objects; generic comparison helpers that call static Equals; code written against the base System.Object pattern.","solutions":["Replace the call with RecordType<A>.Equality(objA, objB) for object-based comparison.","Use RecordType<A>.EqualityTyped((A, A)) when both operands are statically typed as A.","If flagged by the compiler as obsolete-warning-turned-error, fix the call site rather than suppressing the warning."],"exampleFix":"// before\nbool same = RecordType<MyRecord>.Equals(a, b); // throws\n\n// after\nbool same = RecordType<MyRecord>.Equality(a, b);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static bool RecordsEqual<A>(A a, A b) where A : Record<A> => RecordType<A>.EqualityTyped(a, b);","tryCatchPattern":null,"preventionTips":["Treat [Obsolete] warnings as errors so this never compiles.","Standardize on RecordType<A>.Equality/EqualityTyped helpers in shared comparison utilities.","Avoid generic helpers that call static Object.Equals on record types."],"tags":["csharp","languageext","records","equality","deprecated"],"backgroundTag":"deprecated-api-usage","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"}