¿Por qué no se nos permite hacer lo siguiente para un registro?
abstract record AA { public abstract bool Equals(AA other); } record BB:AA { public override bool Equals(AA other)// error as it is already implemented { //do some thing } }mientras que es totalmente aceptable para las clases?
abstract class AA { public abstract bool Equals(AA other); } class BB:AA { public override bool Equals(AA other) { //do some thing } }Por cierto, estoy haciendo esta implementación para hacer cumplir la verificación de Igualdad para que se conecte en cascada a sus clases derivadas.
Editar: solo para dar contexto sobre por qué estoy interesado en esto porque actualmente estoy creando una biblioteca/ generador automático para IEquatable.
Edit/Info 2: Basado en los comentarios, he hecho algunas pruebas. dado que el método de registro abstracto Equals no se puede anular, intenté dejarlo como está.
public abstract record AA { public int Prop1 { get; set; } public string? Prop2 { get; set; } public string? Prop5 { get; set; } public abstract bool Equals(AA? other); } public record BB : AA { public string? Prop3 { get; set; } }El resultado me da un error de System.BadImageFormatException: formato IL incorrecto.
En general, el método Equals abstracto en los registros no es solo una implementación innecesaria, sino que también es mala.
Esto se debe a que el compilador ya implementa métodos de igualdad para registros. Compruebe la igualdad de valores de los registros:
Para implementar la igualdad de valores, el compilador sintetiza los siguientes métodos:
Una anulación de Object.Equals(Object).
Este método se utiliza como base para el método estático Object.Equals(Object, Object) cuando ambos parámetros no son nulos.
Un método Equals virtual cuyo parámetro es el tipo de registro. Este método implementa IEquatable.
Una anulación de Object.GetHashCode().
Anula los operadores == y !=.
Significa que no es necesario aplicar la implementación del método Equals en el registro abstracto base.
Si aún desea tener una implementación del método Equals personalizado y derivar de algún registro base, puede hacerlo declarando el método Equals virtual con el tipo derivado como argumento:
abstract record AA { // Redundant in case of records and can be omitted. public abstract bool Equals(AA other); } record BB : AA { public virtual bool Equals(BB other) { throw new NotImplementedException(); } }