Definición de una propiedad en un registro dos veces
En C # 9, se puede definir una propiedad con el mismo nombre en un registro tanto en su constructor principal como en su cuerpo:
record Cat(int PawCount)
{
public int PawCount { get; init; }
}
Este código se compila sin errores.
Al inicializar una instancia de dicho registro, el valor proporcionado al constructor se ignora por completo:
Console.WriteLine(new Cat(4));
Console.WriteLine(new Cat(4) { PawCount = 1 });
huellas dactilares
Cat { PawCount = 0 }
Cat { PawCount = 1 }
¿Este comportamiento es correcto o es un error? Si es correcto, ¿cuáles son los casos en los que es útil?
Esperaba que el compilador rechazara este código con un error como 'El tipo Cat
ya contiene una definición para PawCount
' o considerara la propiedad en el constructor y en el cuerpo de la misma manera, realizando su inicialización desde el constructor. La última variante podría ser útil para proporcionar a la propiedad un captador y / o inicializador personalizado sin tener que reescribir todas las propiedades del registro posicional en su cuerpo.
El comportamiento real no tiene sentido para mí.
Respuestas
La forma correcta de hacer esto es:
record Cat(int PawCount)
{
public int PawCount { get; init; } = PawCount;
}
Esto es útil ya que le permite hacer, por ejemplo, validación
record Cat(int PawCount)
{
private int _pawCount;
public int PawCount {
get => _pawCount;
init => _pawCount = value < 0 ? throw new ArgumentException() : value;
} = PawCount;
}
La especificación para esto está aquí: https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md#members-of-a-record-type
Los miembros se sintetizan a menos que se declare un miembro con una firma "coincidente" en el cuerpo del registro o se herede un miembro no virtual concreto accesible con una firma "coincidente". Se considera que dos miembros coinciden si tienen la misma firma o se considerarían "ocultos" en un escenario de herencia.
Entonces, dado que ya existe una propiedad con el mismo nombre que el parámetro, el compilador no sintetizará una PawCount
propiedad, por lo que simplemente ignorará el parámetro en silencio a menos que lo use usted mismo explícitamente.