Miembros con cuerpo de expresión (Guía de programación de C#)
Las definiciones de cuerpos de expresión permiten proporcionar la implementación de un miembro de una forma concisa y legible. Se puede usar una definición de cuerpo de expresión siempre que la lógica de cualquier miembro compatible, como un método o propiedad, se componga de una expresión única. Una definición de cuerpo de expresión tiene la siguiente sintaxis general:
member => expression;
donde expresión es una expresión válida.
Las definiciones del cuerpo de expresiones se pueden usar con los miembros de tipo siguientes:
Métodos
Un método con cuerpo de expresión consta de una sola expresión que devuelve un valor cuyo tipo coincide con el tipo de valor devuelto del método, o bien, para los métodos que devuelven void
, que realiza alguna operación. Por ejemplo, los tipos que reemplazan el método ToString normalmente incluyen una sola expresión que devuelve la representación de cadena del objeto actual.
En el ejemplo siguiente se define una clase Person
que reemplaza el método ToString con una definición de cuerpo de expresión. También define un método DisplayName
que muestra un nombre en la consola. La palabra clave return
no se usa en la definición de cuerpo de expresión de ToString
.
using System;
namespace ExpressionBodiedMembers;
public class Person
{
public Person(string firstName, string lastName)
{
fname = firstName;
lname = lastName;
}
private string fname;
private string lname;
public override string ToString() => $"{fname} {lname}".Trim();
public void DisplayName() => Console.WriteLine(ToString());
}
class Example
{
static void Main()
{
Person p = new Person("Mandy", "Dejesus");
Console.WriteLine(p);
p.DisplayName();
}
}
Para más información, vea Métodos (Guía de programación de C#).
Propiedades de solo lectura
Puede usar la definición del cuerpo de expresiones para implementar una propiedad de solo lectura. Para ello, use la sintaxis siguiente:
PropertyType PropertyName => expression;
En el ejemplo siguiente se define una clase Location
cuya propiedad Name
de solo lectura se implementa como una definición de cuerpo de expresión que devuelve el valor del campo privado locationName
:
public class Location
{
private string locationName;
public Location(string name)
{
locationName = name;
}
public string Name => locationName;
}
Para más información sobre las propiedades, vea Propiedades (Guía de programación de C#).
Propiedades
Puede usar las definiciones del cuerpo de expresiones para implementar los descriptores de acceso get
y set
de propiedades. En el ejemplo siguiente se muestra cómo hacerlo:
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
Para más información sobre las propiedades, vea Propiedades (Guía de programación de C#).
Eventos
Del mismo modo, los descriptores de acceso remove
y add
de los eventos pueden tener forma de expresión:
public class ChangedEventArgs : EventArgs
{
public required int NewValue { get; init; }
}
public class ObservableNum(int _value)
{
public event EventHandler<ChangedEventArgs> ChangedGeneric = default!;
public event EventHandler Changed
{
// Note that, while this is syntactically valid, it won't work as expected because it's creating a new delegate object with each call.
add => ChangedGeneric += (sender, args) => value(sender, args);
remove => ChangedGeneric -= (sender, args) => value(sender, args);
}
public int Value
{
get => _value;
set => ChangedGeneric?.Invoke(this, new() { NewValue = (_value = value) });
}
}
Para obtener más información sobre los eventos, consulte Eventos (Guía de programación de C#).
Constructores
Una definición de cuerpo de expresión para un constructor normalmente consta de una expresión de asignación única o una llamada de método que controla los argumentos del constructor o inicializa el estado de la instancia.
En el ejemplo siguiente se define una clase Location
cuyo constructor tiene un único parámetro de cadena denominado name. La definición del cuerpo de expresión asigna el argumento a la propiedad Name
.
public class Location
{
private string locationName;
public Location(string name) => Name = name;
public string Name
{
get => locationName;
set => locationName = value;
}
}
Para más información, vea Constructores (Guía de programación de C#).
Finalizadores
Una definición de cuerpo de expresión para un finalizador normalmente contiene instrucciones de limpieza, como las instrucciones que liberan recursos no administrados.
En el ejemplo siguiente se define un finalizador que usa una definición de cuerpo de expresión para indicar que el finalizador se ha llamado.
public class Destroyer
{
public override string ToString() => GetType().Name;
~Destroyer() => Console.WriteLine($"The {ToString()} finalizer is executing.");
}
Para más información, vea Finalizadores (Guía de programación de C#).
Indizadores
Como las propiedades, los descriptores de acceso get
y set
del indizador constan de las definiciones de cuerpos de expresión si el descriptor de acceso get
está formado por una sola expresión que devuelve un valor o el descriptor de acceso set
realiza una asignación simple.
En el ejemplo siguiente se define una clase denominada Sports
que incluye una matriz String interna que contiene los nombres de algunos deportes. Los descriptores de acceso get
y set
del indizador se implementan como definiciones de cuerpos de expresión.
using System;
using System.Collections.Generic;
namespace SportsExample;
public class Sports
{
private string[] types = [ "Baseball", "Basketball", "Football",
"Hockey", "Soccer", "Tennis",
"Volleyball" ];
public string this[int i]
{
get => types[i];
set => types[i] = value;
}
}
Para más información, vea Indizadores (Guía de programación de C#).