louthy/language-ext · error · InvalidOperationException
Don't use Equals - use either RecordType
Error message
Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped
What it means
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]).
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.
Example fix
// before bool same = RecordType<MyRecord>.Equals(a, b); // throws // after bool same = RecordType<MyRecord>.Equality(a, b);
Defensive patterns
Strategy: type-guard
Type guard
static bool RecordsEqual<A>(A a, A b) where A : Record<A> => RecordType<A>.EqualityTyped(a, b);
Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.
Related errors
- Don't use Equals - use either RecordType
- Eq attribute should have a struct type that derives from…
- Ord attribute should have a struct type that derives from…
- Hashable attribute should have a struct type that derives…
- s
AI-assisted analysis of louthy/language-ext@2f0e362824 (2026-09-15).
Data as JSON: /api/errors/6b9d41a6102b346f.
Report an issue: GitHub.
Appendix: source
Thrown at LanguageExt.Core/DataTypes/Record/RecordType.cs:50
/// <summary>
/// General ToString function
/// </summary>
public new static Func<A, string> ToString => RecordTypeToString<A>.ToString;
/// <summary>
/// De-serialise an A
/// </summary>
public static Action<A, SerializationInfo> SetObjectData => RecordTypeSetObjectData<A>.SetObjectData;
/// <summary>
/// Serialise an A
/// </summary>
public static Action<A, SerializationInfo> GetObjectData => RecordTypeGetObjectData<A>.GetObjectData;
[Obsolete("Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped")]
public new static bool Equals(object objA, object objB) =>
throw new InvalidOperationException("Don't use Equals - use either RecordType<A>.Equality or RecordType<A>.EqualityTyped");
}
internal static class RecordTypeIncludeBase<A>
{
internal static readonly bool IncludeBase;
static RecordTypeIncludeBase() =>
IncludeBase = !typeof(A).CustomAttributes
.AsIterable()
.Exists(a => a.AttributeType.Name == nameof(IgnoreBaseAttribute));
}
internal static class RecordTypeHash<A>
{
internal static readonly Func<A, int> Hash;
static RecordTypeHash() =>
Hash = IL.GetHashCode<A>(RecordTypeIncludeBase<A>.IncludeBase);View on GitHub (pinned to 2f0e362824)