Propiedades (Guía de programación de C#)Properties (C# Programming Guide)

Una propiedad es un miembro que proporciona un mecanismo flexible para leer, escribir o calcular el valor de un campo privado.A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. Las propiedades se pueden usar como si fueran miembros de datos públicos, pero en realidad son métodos especiales denominados descriptores de acceso.Properties can be used as if they are public data members, but they are actually special methods called accessors. Esto permite acceder fácilmente a los datos a la vez que proporciona la seguridad y la flexibilidad de los métodos.This enables data to be accessed easily and still helps promote the safety and flexibility of methods.

Información general sobre propiedadesProperties overview

  • Las propiedades permiten que una clase exponga una manera pública de obtener y establecer valores, a la vez que se oculta el código de implementación o verificación.Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code.

  • Para devolver el valor de la propiedad se usa un descriptor de acceso de propiedad get, mientras que para asignar un nuevo valor se emplea un descriptor de acceso de propiedad set.A get property accessor is used to return the property value, and a set property accessor is used to assign a new value. Estos descriptores de acceso pueden tener diferentes niveles de acceso.These accessors can have different access levels. Para más información, vea Restringir la accesibilidad del descriptor de acceso.For more information, see Restricting Accessor Accessibility.

  • La palabra clave value se usa para definir el valor que va a asignar el descriptor de acceso set.The value keyword is used to define the value being assigned by the set accessor.

  • Las propiedades pueden ser de lectura y escritura (en ambos casos tienen un descriptor de acceso get y set), de solo lectura (tienen un descriptor de acceso get, pero no set) o de solo escritura (tienen un descriptor de acceso set, pero no get).Properties can be read-write (they have both a get and a set accessor), read-only (they have a get accessor but no set accessor), or write-only (they have a set accessor, but no get accessor). Las propiedades de solo escritura son poco frecuentes y se suelen usar para restringir el acceso a datos confidenciales.Write-only properties are rare and are most commonly used to restrict access to sensitive data.

  • Las propiedades simples que no necesitan ningún código de descriptor de acceso personalizado se pueden implementar como definiciones de cuerpos de expresión o como propiedades implementadas automáticamente.Simple properties that require no custom accessor code can be implemented either as expression body definitions or as auto-implemented properties.

Propiedades con campos de respaldoProperties with backing fields

Un patrón básico para implementar una propiedad conlleva el uso de un campo de respaldo privado para establecer y recuperar el valor de la propiedad.One basic pattern for implementing a property involves using a private backing field for setting and retrieving the property value. El descriptor de acceso get devuelve el valor del campo privado y el descriptor de acceso set puede realizar alguna validación de datos antes de asignar un valor al campo privado.The get accessor returns the value of the private field, and the set accessor may perform some data validation before assigning a value to the private field. Ambos descriptores de acceso además pueden realizar algún cálculo o conversión en los datos antes de que se almacenen o se devuelvan.Both accessors may also perform some conversion or computation on the data before it is stored or returned.

En el ejemplo siguiente se muestra este patrón.The following example illustrates this pattern. En este ejemplo, la clase TimePeriod representa un intervalo de tiempo.In this example, the TimePeriod class represents an interval of time. Internamente, la clase almacena el intervalo de tiempo en segundos en un campo privado denominado _seconds.Internally, the class stores the time interval in seconds in a private field named _seconds. Una propiedad de lectura y escritura denominada Hours permite al cliente especificar el intervalo de tiempo en horas.A read-write property named Hours allows the customer to specify the time interval in hours. Los descriptores de acceso get y set realizan la conversión necesaria entre horas y segundos.Both the get and the set accessors perform the necessary conversion between hours and seconds. Además, el descriptor de acceso set valida los datos e inicia una excepción ArgumentOutOfRangeException si el número de horas no es válido.In addition, the set accessor validates the data and throws an ArgumentOutOfRangeException if the number of hours is invalid.

using System;

class TimePeriod
{
   private double _seconds;

   public double Hours
   {
       get { return _seconds / 3600; }
       set { 
          if (value < 0 || value > 24)
             throw new ArgumentOutOfRangeException(
                   $"{nameof(value)} must be between 0 and 24.");

          _seconds = value * 3600; 
       }
   }
}

class Program
{
   static void Main()
   {
       TimePeriod t = new TimePeriod();
       // The property assignment causes the 'set' accessor to be called.
       t.Hours = 24;

       // Retrieving the property causes the 'get' accessor to be called.
       Console.WriteLine($"Time in hours: {t.Hours}");
   }
}
// The example displays the following output:
//    Time in hours: 24

Definiciones de cuerpos de expresiónExpression body definitions

Los descriptores de acceso de propiedad suelen constar de instrucciones de una sola línea que simplemente asignan o devuelven el resultado de una expresión.Property accessors often consist of single-line statements that just assign or return the result of an expression. Puede implementar estas propiedades como miembros con forma de expresión.You can implement these properties as expression-bodied members. Las definiciones de cuerpos de expresión constan del símbolo => seguido de la expresión que se va a asignar a la propiedad o a recuperar de ella.Expression body definitions consist of the => symbol followed by the expression to assign to or retrieve from the property.

A partir de C# 6, las propiedades de solo lectura pueden implementar el descriptor de acceso get como miembro con forma de expresión.Starting with C# 6, read-only properties can implement the get accessor as an expression-bodied member. En este caso, no se usan ni la palabra clave del descriptor de acceso get ni la palabra clave return.In this case, neither the get accessor keyword nor the return keyword is used. En el ejemplo siguiente se implementa la propiedad de solo lectura Name como miembro con forma de expresión.The following example implements the read-only Name property as an expression-bodied member.

using System;

public class Person
{
   private string _firstName;
   private string _lastName;
   
   public Person(string first, string last)
   {
      _firstName = first;
      _lastName = last;
   }

   public string Name => $"{_firstName} {_lastName}";   
}

public class Example
{
   public static void Main()
   {
      var person = new Person("Isabelle", "Butts");
      Console.WriteLine(person.Name);
   }
}
// The example displays the following output:
//      Isabelle Butts

A partir de C# 7.0, los descriptores de acceso get y set se pueden implementar como miembros con forma de expresión.Starting with C# 7.0, both the get and the set accessor can be implemented as expression-bodied members. En este caso, las palabras clave get y set deben estar presentes.In this case, the get and set keywords must be present. En el ejemplo siguiente se muestra el uso de definiciones de cuerpos de expresión para ambos descriptores de acceso.The following example illustrates the use of expression body definitions for both accessors. Observe que no se usa la palabra clave return con el descriptor de acceso get.Note that the return keyword is not used with the get accessor.

using System;

public class SaleItem
{
   string _name;
   decimal _cost;
   
   public SaleItem(string name, decimal cost)
   {
      _name = name;
      _cost = cost;
   }

   public string Name 
   {
      get => _name;
      set => _name = value;
   }

   public decimal Price
   {
      get => _cost;
      set => _cost = value; 
   }
}

class Program
{
   static void Main(string[] args)
   {
      var item = new SaleItem("Shoes", 19.95m);
      Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");
   }
}
// The example displays output like the following:
//       Shoes: sells for $19.95



Propiedades implementadas automáticamenteAuto-implemented properties

En algunos casos, los descriptores de acceso de propiedad get y set simplemente asignan un valor a un campo de respaldo o recuperan un valor de él sin incluir ninguna lógica adicional.In some cases, property get and set accessors just assign a value to or retrieve a value from a backing field without including any additional logic. Mediante las propiedades implementadas automáticamente, puede simplificar el código y conseguir que el compilador de C# le proporcione el campo de respaldo de forma transparente.By using auto-implemented properties, you can simplify your code while having the C# compiler transparently provide the backing field for you.

Si una propiedad tiene un descriptor de acceso get y set, ambos deben ser implementados automáticamente.If a property has both a get and a set accessor, both must be auto-implemented. Una propiedad implementada automáticamente se define mediante las palabras clave get y set sin proporcionar ninguna implementación.You define an auto-implemented property by using the get and set keywords without providing any implementation. El ejemplo siguiente repite el anterior, salvo que Name y Price son propiedades implementadas automáticamente.The following example repeats the previous one, except that Name and Price are auto-implemented properties. Tenga en cuenta que en el ejemplo también se quita el constructor parametrizado, por lo que los objetos SaleItem ahora se inicializan con una llamada al constructor sin parámetros y un inicializador de objeto.Note that the example also removes the parameterized constructor, so that SaleItem objects are now initialized with a call to the parameterless constructor and an object initializer.

using System;

public class SaleItem
{
   public string Name 
   { get; set; }

   public decimal Price
   { get; set; }
}

class Program
{
   static void Main(string[] args)
   {
      var item = new SaleItem{ Name = "Shoes", Price = 19.95m };
      Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");
   }
}
// The example displays output like the following:
//       Shoes: sells for $19.95



Especificación del lenguaje C#C# Language Specification

Para obtener más información, vea la sección Propiedades de la Especificación del lenguaje C#.For more information, see Properties in the C# Language Specification. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.The language specification is the definitive source for C# syntax and usage.

Vea tambiénSee also