La nueva palabra clave field en C# 14
Las auto-propiedades en C# son concisas, pero en el momento en que necesitas lógica de validación o transformación en un setter, siempre has tenido que abandonarlas por completo y escribir una propiedad completa con un campo de respaldo manual. Ese salto de una línea a siete es un costo elevado por agregar una sola cláusula de protección. C# 14 introduce la palabra clave field para cerrar esa brecha, permitiéndote personalizar un getter o setter mientras el compilador sigue gestionando el campo de respaldo por ti.
En su video "The New field Keyword in C# 14", Tim Corey demuestra el problema que resuelve esta función, recorre ejemplos prácticos de validación de setters, y cubre un conflicto de nombres que debes conocer antes de hacer la actualización. Seguiremos cada paso en detalle para que puedas empezar a usar field en tus propias propiedades con confianza.
La Configuración: Un Modelo de Persona Simple
[0:12 - 1:07] Tim comienza con una aplicación de consola que se ejecuta en .NET 10 y Visual Studio 2026. La demostración se centra en una clase Person con algunas propiedades:
public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }
public required string FirstName { get; set; }
public required string LastName { get; set; }
public int Age { get; set; }
También hay una propiedad Demo respaldada por un campo privado, que se vuelve relevante una vez que surge el conflicto de nombres. En Program.cs, Tim crea una instancia con FirstName = "Tim" y LastName = "Corey", luego imprime el apellido, la edad y el valor de demostración. Todo se muestra como se esperaba: "Corey", 0 (el entero por defecto), y "test".
El Problema: Las Auto-Propiedades Aceptan Datos Incorrectos
[1:23 - 2:49] El problema surge cuando Tim asigna null a LastName después de la construcción:
p.LastName = null;
p.LastName = null;
Aunque LastName está marcado como required y es de tipo cadena no anulable, la asignación se compila. El modificador required solo aplica que se proporcione un valor durante la inicialización del objeto; no impide que alguien configure la propiedad a null posteriormente. El resultado es un apellido en blanco en tiempo de ejecución sin que se lance error.
Esta es una verdadera brecha en la integridad de los datos. El sistema de tipos te advierte con una ondulación de referencia nullable, pero eso es una sugerencia en tiempo de compilación, no una protección en tiempo de ejecución. Si tu aplicación depende de que LastName contenga siempre una cadena válida, las auto-propiedades por sí solas no pueden hacer cumplir ese contrato.
La Solución Antigua: Propiedades Completas con Campos de Respaldo Manuales
[2:58 - 4:19] Antes de C# 14, la solución estándar era convertir la auto-propiedad en una propiedad completa con un campo de respaldo explícito:
private string _lastName;
public required string LastName
{
get => _lastName;
set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}
private string _lastName;
public required string LastName
{
get => _lastName;
set => _lastName = value ?? throw new ArgumentNullException(nameof(LastName));
}
Tim ejecuta esto y confirma que la excepción se activa correctamente: "El valor no puede ser nulo. Nombre del parámetro: LastName." El enfoque funciona, pero requiere declarar un campo privado, conectar tanto el getter como el setter, y repetir el nombre de la propiedad en múltiples líneas. Para una sola regla de validación, eso es mucho ceremonial.
El getter en este caso no hace nada especial; devuelve el campo sin cambios. Sin embargo, todavía tienes que escribirlo explícitamente porque la sintaxis exige ambas mitades una vez que abandonas el territorio de la auto-propiedad. Tim enmarca esta verbosidad como la motivación detrás de la nueva función.
La Solución C# 14: La Palabra Clave field
[4:23 - 5:47] C# 14 introduce un término medio. En lugar de declarar un campo de respaldo privado tú mismo, utilizas la palabra clave contextual field dentro de un getter o setter para referenciar directamente el campo de respaldo generado por el compilador:
public required string LastName
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}
public required string LastName
{
get;
set => field = value ?? throw new ArgumentNullException(nameof(LastName));
}
El getter sigue siendo un get; autoimplementado sin necesidad de cuerpo. El setter utiliza field para asignar el value entrante después de la validación. El compilador crea y gestiona el campo de respaldo detrás de escena, al igual que lo hace con una auto-propiedad estándar.
Ejecutar la demostración produce el mismo ArgumentNullException en la asignación nula. El comportamiento es idéntico a la versión con respaldo manual, comprimida de siete líneas a un bloque enfocado que solo personaliza lo que necesita personalización. Mantienes el getter de auto-propiedad, agregas lógica solo al setter, y evitas la declaración del campo manual por completo.
Esto proporciona un paso intermedio útil entre una auto-propiedad simple (una línea, sin validación) y una propiedad completa (siete o más líneas, control completo). Cuando tu lógica solo toca el setter, ya no pagas el costo sintáctico de reescribir también el getter.
Validando la Edad con un Setter Guard
[6:16 - 7:39] Para mostrar que field no se limita a comprobaciones nulas, Tim añade validación de rango a la propiedad Age:
public int Age
{
get;
set
{
if (value > 0 && value < 120)
field = value;
}
}
public int Age
{
get;
set
{
if (value > 0 && value < 120)
field = value;
}
}
Aquí, el setter ignora silenciosamente los valores fuera de un rango razonable. Asignar -5 deja Age en su valor predeterminado de cero porque la condición no se cumple y field nunca es escrita. Tim señala que podrías lanzar una excepción en su lugar, pero el enfoque silencioso demuestra que el cuerpo del setter puede contener cualquier lógica que necesites mientras sigues confiando en field para almacenamiento.
El patrón se aplica ampliamente: restringiendo rangos numéricos, eliminando espacios en blanco de cadenas, normalizando mayúsculas, o cualquier transformación que quieras aplicar cada vez que se establece una propiedad.
Conflictos de Nombres con Variables field Existentes
[7:39 - 9:43] Tim introduce un caso límite deliberado. La clase de demostración tiene un miembro privado denominado literalmente field:
private string field = "test";
private string field = "test";
Una vez que C# 14 está activo, el compilador trata field dentro de un acceso a propiedad como la palabra clave en lugar de la variable. Eso significa que una propiedad que hace referencia a field lee en silencio desde el almacenamiento oculto detrás de la propiedad (que está vacío) en lugar del miembro de cadena que contiene "test". La salida cambia a en blanco sin error de compilación, solo una advertencia.
Existen dos soluciones. Anteponer this.field le dice al compilador que te refieres al miembro a nivel de clase, no a la palabra clave. Alternativamente, el escape @field funciona de la misma manera:
// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;
// Both refer to the instance variable, not the keyword
string demo => this.field;
string demo => @field;
La fuerte recomendación de Tim es renombrar cualquier variable llamada field al actualizar a C# 14. Una rápida "Renombrar todo" en tu IDE elimina la ambigüedad permanentemente. El conflicto solo surge dentro de los accesorios de propiedad; Los constructores y métodos resuelven field al nombre de la variable como se espera, ya que esos contextos no tienen un almacén de respaldo implícito.
Conclusión: Menos Plantilla, el Mismo Control
[10:04 - 10:28] La palabra clave field llena un vacío práctico en el código C# cotidiano. Las propiedades que necesitan una cláusula de protección o transformación ya no requieren una reescritura completa con campos de respaldo manuales. Personalizas solo el accesor que necesita lógica y dejas el otro como una implementación automática estándar.
Conclusión
[10:28 - 10:35] Para resumir: la palabra clave field de C# 14 te da acceso directo al almacén de respaldo implícito dentro de cualquier acceso a propiedad. Úsalo para agregar validación de setters, transformaciones de getters, o ambos, sin abandonar la sintaxis de auto-propiedad para las partes que no necesitan personalización.
Antes de actualizar, busca en tu base de código cualquier variable llamada field y renómbralas. Esa única precaución evita el único problema real que introduce esta función. Más allá de eso, es una reducción limpia en la plantilla que se ajusta naturalmente a cómo la mayoría de los desarrolladores ya estructuran sus modelos.
Consejo de ejemplo: Si solo necesitas validar el setter, deja el getter como un get; simple sin cuerpo. El compilador lo maneja como un getter de auto-propiedad, y evitas escribir una declaración de retorno que no añade nada.
Mira el video completo video en su Canal de YouTube y obtén más información sobre las características del lenguaje C#.
