Partilhar via


Propriedades (Guia de Programação em C#)

Uma propriedade é um membro que fornece um mecanismo flexível para ler, escrever ou calcular o valor de um campo privado. As propriedades podem ser usadas como se fossem membros de dados públicos, mas são métodos especiais chamados acessadores. Esse recurso permite que os dados sejam acessados facilmente e ainda ajuda a promover a segurança e a flexibilidade dos métodos.

Visão geral das propriedades

  • As propriedades permitem que uma classe exponha uma maneira pública de obter e definir valores, enquanto oculta o código de implementação ou verificação.
  • Um acessador de propriedade get é usado para retornar o valor da propriedade e um acessador de propriedade definido é usado para atribuir um novo valor. Um acessador de propriedade init é usado para atribuir um novo valor somente durante a construção do objeto. Esses acessadores podem ter diferentes níveis de acesso. Para obter mais informações, consulte Restringindo a acessibilidade do Accessor.
  • A palavra-chave value é usada para definir o valor que o set acessador ou init acessador está atribuindo.
  • As propriedades podem ser leitura-gravação (elas têm um get acessador e um set acessador), somente leitura (elas têm um get acessador, mas não set acessam) ou somente gravação (elas têm um set acessador, mas não get acessam). As propriedades somente gravação são raras e são mais comumente usadas para restringir o acesso a dados confidenciais.
  • Propriedades simples que não exigem código de acesso personalizado podem ser implementadas como definições de corpo de expressão ou como propriedades implementadas automaticamente.

Propriedades com campos de apoio

Um padrão básico para implementar uma propriedade envolve o uso de um campo de suporte privado para definir e recuperar o valor da propriedade. O get acessador retorna o valor do campo privado e o set acessador pode executar alguma validação de dados antes de atribuir um valor ao campo privado. Ambos os acessadores também podem realizar alguma conversão ou cálculo nos dados antes que eles sejam armazenados ou retornados.

O exemplo a seguir ilustra esse padrão. Neste exemplo, a TimePeriod classe representa um intervalo de tempo. Internamente, a classe armazena o intervalo de tempo em segundos em um campo privado chamado _seconds. Uma propriedade de leitura-gravação chamada Hours permite que o cliente especifique o intervalo de tempo em horas. Tanto o acessador quanto o getset acessador realizam a conversão necessária entre horas e segundos. Além disso, o set acessador valida os dados e lança um ArgumentOutOfRangeException se o número de horas for inválido.

public class TimePeriod
{
    private double _seconds;

    public double Hours
    {
        get { return _seconds / 3600; }
        set
        {
            if (value < 0 || value > 24)
                throw new ArgumentOutOfRangeException(nameof(value),
                      "The valid range is between 0 and 24.");

            _seconds = value * 3600;
        }
    }
}

Você pode acessar propriedades para obter e definir o valor, conforme mostrado no exemplo a seguir:

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

Definições do corpo da expressão

Os acessadores de propriedade geralmente consistem em instruções de linha única que apenas atribuem ou retornam o resultado de uma expressão. Você pode implementar essas propriedades como membros com corpo de expressão. As definições do corpo da expressão consistem no => símbolo seguido da expressão a ser atribuída ou recuperada da propriedade.

As propriedades somente leitura podem implementar o get acessador como um membro com corpo de expressão. Neste caso, nem a get palavra-chave acessor nem a palavra-chave são return usadas. O exemplo a seguir implementa a propriedade somente Name leitura como um membro com corpo de expressão.

public class Person
{
    private string _firstName;
    private string _lastName;

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

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

Tanto o acessador quanto o getset acessador podem ser implementados como membros com corpo de expressão. Neste caso, as get palavras-chave e set devem estar presentes. O exemplo a seguir ilustra o uso de definições de corpo de expressão para ambos os acessadores. A return palavra-chave não é usada com o get acessador.

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;
    }
}

Propriedades implementadas automaticamente

Em alguns casos, a propriedade get e set os acessadores apenas atribuem um valor ou recuperam um valor de um campo de suporte sem incluir qualquer lógica extra. Usando propriedades implementadas automaticamente, você pode simplificar seu código enquanto o compilador C# fornece de forma transparente o campo de suporte para você.

Se uma propriedade tiver um get acessador e um set (ou um get e um init), ambos deverão ser implementados automaticamente. Você define uma propriedade implementada automaticamente usando as get palavras-chave e set sem fornecer nenhuma implementação. O exemplo a seguir repete o anterior, exceto que Name e Price são propriedades implementadas automaticamente. O exemplo também remove o construtor parametrizado, de modo que SaleItem os objetos agora são inicializados com uma chamada para o construtor sem parâmetros e um inicializador de objeto.

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

    public decimal Price
    { get; set; }
}

As propriedades implementadas automaticamente podem declarar diferentes acessibilidades para os get e set acessadores. Normalmente, você declara um acessador público get e um acessador privado set . Você pode saber mais no artigo sobre como restringir a acessibilidade do acessor.

Propriedades obrigatórias

A partir do C# 11, você pode adicionar o membro para forçar o código do required cliente a inicializar qualquer propriedade ou campo:

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

    public required decimal Price
    { get; set; }
}

Para criar um SaleItem, você deve definir as Name propriedades e Price usando inicializadores de objeto, conforme mostrado no código a seguir:

var item = new SaleItem { Name = "Shoes", Price = 19.95m };
Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");

Especificação da linguagem C#

Para obter mais informações, consulte Propriedades na especificação da linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso do C#.

Consulte também