Compartilhar via


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

Um campo é uma variável de qualquer tipo que é declarada diretamente em uma classe ou struct. Os campos são membros do tipo que os contém.

Uma classe ou um struct podem ter campos de instância, estáticos ou ambos. Os campos de instância são específicos a uma instância de um tipo. Se você tem uma classe T, com um campo de instância F, você pode criar dois objetos do tipo T e modificar o valor de F em cada objeto sem afetar o valor no outro objeto. Por outro lado, um campo estático pertence ao próprio tipo e é compartilhado entre todas as instâncias desse tipo. Você só pode acessar o campo estático usando o nome do tipo. Se você acessar o campo estático por meio de um nome de instância, receberá o erro em tempo de compilação CS0176.

Em geral, você deve declarar a acessibilidade private ou protected para campos. Os dados que o tipo expõe para o código de cliente devem ser fornecidos por meio de métodos, propriedades e indexadores. Usando esses constructos para acesso indireto aos campos internos, você pode proteger contra valores de entrada inválidos. Um campo particular que armazena os dados expostos por uma propriedade pública é chamado de repositório de backup ou de campo de suporte. Você pode declarar campos public, mas não pode impedir que o código que usa seu tipo defina esse campo como um valor inválido ou altere os dados de um objeto.

Os campos normalmente armazenam os dados que devem estar acessíveis a mais de um método de tipo e devem ser armazenados por mais tempo que o tempo de vida de qualquer método único. Por exemplo, um tipo que representa uma data do calendário pode ter três campos de inteiros: um para o mês, um para o dia e outro para o ano. As variáveis que não são usadas fora do escopo de um método único devem ser declaradas como variáveis locais dentro do próprio corpo do método.

Os campos são declarados no bloco da classe ou do struct, especificando o nível de acesso, seguido pelo tipo e pelo nome do campo. Por exemplo:

public class CalendarEntry
{

    // private field (Located near wrapping "Date" property).
    private DateTime _date;

    // Public property exposes _date field safely.
    public DateTime Date
    {
        get
        {
            return _date;
        }
        set
        {
            // Set some reasonable boundaries for likely birth dates.
            if (value.Year > 1900 && value.Year <= DateTime.Today.Year)
            {
                _date = value;
            }
            else
            {
                throw new ArgumentOutOfRangeException("Date");
            }
        }
    }

    // public field (Generally not recommended).
    public string? Day;

    // Public method also exposes _date field safely.
    // Example call: birthday.SetDate("1975, 6, 30");
    public void SetDate(string dateString)
    {
        DateTime dt = Convert.ToDateTime(dateString);

        // Set some reasonable boundaries for likely birth dates.
        if (dt.Year > 1900 && dt.Year <= DateTime.Today.Year)
        {
            _date = dt;
        }
        else
        {
            throw new ArgumentOutOfRangeException("dateString");
        }
    }

    public TimeSpan GetTimeSpan(string dateString)
    {
        DateTime dt = Convert.ToDateTime(dateString);

        if (dt.Ticks < _date.Ticks)
        {
            return _date - dt;
        }
        else
        {
            throw new ArgumentOutOfRangeException("dateString");
        }
    }
}

Para acessar um campo em uma instância, adicione um ponto após o nome da instância, seguido pelo nome do campo, como em instancename._fieldName. Por exemplo:

CalendarEntry birthday = new CalendarEntry();
birthday.Day = "Saturday";

Um campo pode receber um valor inicial, usando o operador de atribuição quando o campo é declarado. Para atribuir automaticamente o campo Day ao "Monday", por exemplo, você poderia declarar Day como no exemplo a seguir:

public class CalendarDateWithInitialization
{
    public string Day = "Monday";
    //...
}

Os campos são inicializados imediatamente antes do construtor para a instância do objeto ser chamado. Se o construtor atribuir o valor de um campo, ele substituirá qualquer valor fornecido durante a declaração do campo. Para obter mais informações, veja Usando construtores.

Observação

Um inicializador de campo não pode fazer referência a outros campos de instância.

Os campos podem ser marcados como public, private, protected, internal, protected internal ou private protected. Esses modificadores de acesso definem como os usuários do tipo podem acessar os campos. Para obter mais informações, consulte Modificadores de Acesso.

Opcionalmente, um campo pode ser declarado static. Os campos estáticos estão disponíveis para chamadores a qualquer momento, mesmo se não existir nenhuma instância do tipo. Para obter mais informações, consulte Classes estáticas e membros de classes estáticas.

Um campo pode ser declarado readonly. Um valor só pode ser atribuído a um campo somente leitura durante a inicialização ou em um construtor. Um campo static readonly é semelhante a uma constante, exceto que o compilador C# não tem acesso ao valor de um campo somente leitura estático em tempo de compilação, mas somente em tempo de execução. Para obter mais informações, consulte Constantes.

Um campo pode ser declarado required. Um campo obrigatório precisa ser inicializado pelo construtor ou por um inicializador de objeto quando um objeto é criado. Adicione o atributo System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute a qualquer declaração de construtor que inicialize todos os membros necessários.

O modificador required não pode ser combinado com o modificador readonly no mesmo campo. No entanto, a propriedade pode ser required e init somente.

A partir do C# 12, os parâmetros do construtor primário são uma alternativa para declarar campos. Quando seu tipo tem dependências que devem ser fornecidas na inicialização, você pode criar um construtor primário que fornece essas dependências. Esses parâmetros podem ser capturados e usados no lugar de campos declarados em seus tipos. No caso de tipos record, os parâmetros do construtor primário são exibidos como propriedades públicas.

Especificação da linguagem C#

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

Confira também