¿Una anulación de iguales en un tipo de referencia siempre significa igualdad de valor?

Sin hacer nada especial por un tipo de referencia,Equals() significaría igualdad de referencia (es decir, el mismo objeto). Si elijo anularEquals() para un tipo de referencia, ¿debería significar siempre que los valores de los dos objetos son equivalentes?

Considera esto mutablePerson clase:

class Person
{
    readonly int Id;

    string FirstName { get; set; }
    string LastName { get; set; }
    string Address { get; set; }
    // ...
}

Dos objetos que representan exactamente a la misma persona siempre tendrán el mismo.Id, pero los otros campos pueden ser diferentes a lo largo del tiempo (es decir, antes / después de un cambio de dirección).

Para este objeto, Igual podría definirse para significar cosas diferentes:

Igualdad de valor: todos los campos son iguales (dos objetos que representan a la misma persona pero con direcciones diferentes devolverían falso)Igualdad de identidad: laIds son iguales (dos objetos que representan a la misma persona pero con direcciones diferentes devolverían verdadero)Igualdad de referencia: es decir, no implementar iguales.

Pregunta: ¿Cuál (si alguno) de estos es preferible para esta clase? (O quizás la pregunta debería ser, "¿cómo esperan la mayoría de los clientes de esta clase que Equals () se comporte?")

Notas:

Usar Value Equality hace que sea más difícil usar esta clase en unaHashset oDictionary

El uso de Identity Equality hace que la relación entre Equals y el= operador extraño (es decir, después de una verificación de dos objetos Person (p1 y p2) devuelve true paraEquals(), es posible que aún desee actualizar su referencia para que apunte al objeto Person "más nuevo", ya que no es un valor equivalente). Por ejemplo, el siguiente código dice extraño: parece que no hace nada, pero en realidad está eliminando p1 y agregando p2:

HashSet<Person> people = new HashSet<Person>();
people.Add(p1);
// ... p2 is an new object that has the same Id as p1 but different Address
people.Remove(p2);
people.Add(p2);

Preguntas relacionadas:

¿Por qué recomienda Microsoft omitir la implementación del operador de igualdad para los tipos de referencia?C # diferencia entre == y iguales ()¿Cuándo debería un reemplazo de clase .NET igual ()? ¿Cuándo no debería?Simplifique la invalidación de Equals (), GetHashCode () en C # para un mejor mantenimiento