Usando propriedades (Guia de Programação em C#)Using Properties (C# Programming Guide)

As propriedades combinam aspectos de métodos e campos.Properties combine aspects of both fields and methods. Para o usuário de um objeto, uma propriedade parece ser um campo. Acessar a propriedade requer a mesma sintaxe.To the user of an object, a property appears to be a field, accessing the property requires the same syntax. Para o implementador de uma classe, uma propriedade consiste em um ou dois blocos de código, que representam um acessador get e/ou um acessador set.To the implementer of a class, a property is one or two code blocks, representing a get accessor and/or a set accessor. O bloco de código para o acessador get é executado quando a propriedade é lida. O bloco de código para o acessador set é executado quando um novo valor é atribuído à propriedade.The code block for the get accessor is executed when the property is read; the code block for the set accessor is executed when the property is assigned a new value. Uma propriedade sem um acessador set é considerada como somente leitura.A property without a set accessor is considered read-only. Uma propriedade sem um acessador get é considerada como somente gravação.A property without a get accessor is considered write-only. Uma propriedade que tem os dois acessadores é leitura/gravação.A property that has both accessors is read-write.

Diferentemente dos campos, as propriedades não são classificadas como variáveis.Unlike fields, properties are not classified as variables. Portanto, você não pode passar uma propriedade como um parâmetro ref ou out.Therefore, you cannot pass a property as a ref or out parameter.

As propriedades têm muitos usos: elas podem validar os dados antes de permitir uma alteração; elas podem expor, de forma transparente, os dados em uma classe em que esses dados são realmente recuperados de outra origem qualquer, como um banco de dados; elas podem executar uma ação quando os dados são alterados, como acionar um evento ou alterar o valor de outros campos.Properties have many uses: they can validate data before allowing a change; they can transparently expose data on a class where that data is actually retrieved from some other source, such as a database; they can take an action when data is changed, such as raising an event, or changing the value of other fields.

As propriedades são declaradas no bloco de classe, especificando o nível de acesso do campo, seguido pelo tipo da propriedade, pelo nome da propriedade e por um bloco de código que declara um acessador get e/ou um acessador set.Properties are declared in the class block by specifying the access level of the field, followed by the type of the property, followed by the name of the property, and followed by a code block that declares a get-accessor and/or a set accessor. Por exemplo: For example:

public class Date
{
    private int _month = 7;  // Backing store

    public int Month
    {
        get => _month;
        set
        {
            if ((value > 0) && (value < 13))
            {
                _month = value;
            }
        }
    }
}

Neste exemplo, Month é declarado como uma propriedade de maneira que o acessador set possa garantir que o valor Month esteja definido entre 1 e 12.In this example, Month is declared as a property so that the set accessor can make sure that the Month value is set between 1 and 12. A propriedade Month usa um campo particular para rastrear o valor real.The Month property uses a private field to track the actual value. O local real dos dados de uma propriedade é conhecido, em geral, como o "repositório de backup" da propriedade.The real location of a property's data is often referred to as the property's "backing store." É comum as propriedades usarem campos particulares como um repositório de backup.It is common for properties to use private fields as a backing store. O campo é marcado como particular para garantir que ele só pode ser alterado ao chamar a propriedade.The field is marked private in order to make sure that it can only be changed by calling the property. Para obter mais informações sobre as restrições de acesso público e particular, consulte Modificadores de acesso.For more information about public and private access restrictions, see Access Modifiers.

As propriedades autoimplementadas fornecem sintaxe simplificada para declarações de propriedade simples.Auto-implemented properties provide simplified syntax for simple property declarations. Para obter mais informações, consulte Propriedades autoimplementadas.For more information, see Auto-Implemented Properties.

O acessador getThe get Accessor

O corpo do acessador get assemelha-se ao de um método.The body of the get accessor resembles that of a method. Ele deve retornar um valor do tipo de propriedade.It must return a value of the property type. A execução do acessador get é equivalente à leitura do valor do campo.The execution of the get accessor is equivalent to reading the value of the field. Por exemplo, quando você estiver retornando a variável particular do acessador get e as otimizações estiverem habilitadas, a chamada ao método do acessador get será embutida pelo compilador, portanto, não haverá nenhuma sobrecarga de chamada de método.For example, when you are returning the private variable from the get accessor and optimizations are enabled, the call to the get accessor method is inlined by the compiler so there is no method-call overhead. No entanto, um método do acessador get virtual não pode ser embutido porque o compilador não sabe, em tempo de compilação, qual método pode ser chamado em tempo de execução.However, a virtual get accessor method cannot be inlined because the compiler does not know at compile-time which method may actually be called at run time. A seguir está um acessador get que retorna o valor de um campo particular _name:The following is a get accessor that returns the value of a private field _name:

class Person
{
    private string _name;  // the name field
    public string Name => _name;     // the Name property
}

Quando você referencia a propriedade, exceto como o destino de uma atribuição, o acessador get é invocado para ler o valor da propriedade.When you reference the property, except as the target of an assignment, the get accessor is invoked to read the value of the property. Por exemplo: For example:

Person person = new Person();
//...

System.Console.Write(person.Name);  // the get accessor is invoked here

O acessador get deve terminar em uma instrução return ou throw e o controle não pode fluir para fora do corpo do acessador.The get accessor must end in a return or throw statement, and control cannot flow off the accessor body.

Alterar o estado do objeto usando o acessador get é um estilo ruim de programação.It is a bad programming style to change the state of the object by using the get accessor. Por exemplo, o acessador a seguir produz o efeito colateral de alterar o estado do objeto sempre que o campo _number é acessado.For example, the following accessor produces the side effect of changing the state of the object every time that the _number field is accessed.

private int _number;
public int Number => _number++;	// Don't do this

O acessador get pode ser usado para retornar o valor do campo ou para calculá-lo e retorná-lo.The get accessor can be used to return the field value or to compute it and return it. Por exemplo: For example:

class Employee
{
    private string _name;
    public string Name => _name != null ? _name : "NA";
}

No segmento de código anterior, se você não Name atribuir um valor NAao imóvel, ele devolverá o valor .In the previous code segment, if you do not assign a value to the Name property, it will return the value NA.

O acessador setThe set Accessor

O acessador set é semelhante a um método cujo tipo de retorno é void.The set accessor resembles a method whose return type is void. Ele usa uma parâmetro implícito chamado value, cujo tipo é o tipo da propriedade.It uses an implicit parameter called value, whose type is the type of the property. No exemplo a seguir, uma acessador set é adicionado à propriedade Name:In the following example, a set accessor is added to the Name property:

class Person
{
    private string _name;  // the name field
    public string Name    // the Name property
    {
        get => _name;
        set => _name = value;
    }
}

Quando você atribui um valor à propriedade, o acessador set é invocado por meio do uso de um argumento que fornece o novo valor.When you assign a value to the property, the set accessor is invoked by using an argument that provides the new value. Por exemplo: For example:

Person person = new Person();
person.Name = "Joe";  // the set accessor is invoked here

System.Console.Write(person.Name);  // the get accessor is invoked here

É um erro usar o nome de parâmetro implícito value, para uma declaração de variável local em um acessador set.It is an error to use the implicit parameter name, value, for a local variable declaration in a set accessor.

ComentáriosRemarks

As propriedades podem ser marcadas como public, private, protected, internal, protected internal ou private protected.Properties can be marked as public, private, protected, internal, protected internal or private protected. Esses modificadores de acesso definem como os usuários da classe podem acessar a propriedade.These access modifiers define how users of the class can access the property. Os acessadores get e set para a mesma propriedade podem ter modificadores de acesso diferentes.The get and set accessors for the same property may have different access modifiers. Por exemplo, o get pode ser public para permitir acesso somente leitura de fora do tipo e o set pode ser private ou protected.For example, the get may be public to allow read-only access from outside the type, and the set may be private or protected. Para obter mais informações, consulte Modificadores de Acesso.For more information, see Access Modifiers.

Uma propriedade pode ser declarada como uma propriedade estática, usando a palavra-chave static.A property may be declared as a static property by using the static keyword. Isso torna a propriedade disponível para chamadores a qualquer momento, mesmo se não existir nenhuma instância da classe.This makes the property available to callers at any time, even if no instance of the class exists. Para obter mais informações, consulte Classes Estáticas e Membros de Classe Estática.For more information, see Static Classes and Static Class Members.

Uma propriedade pode ser marcada como uma propriedade virtual, usando a palavra-chave virtual.A property may be marked as a virtual property by using the virtual keyword. Isso habilita as classes derivadas a substituírem o comportamento da propriedade, usando a palavra-chave override.This enables derived classes to override the property behavior by using the override keyword. Para obter mais informações sobre essas opções, consulte Herança.For more information about these options, see Inheritance.

Uma propriedade que substitui uma propriedade virtual também pode ser sealed, especificando que ela não é mais virtual para classes derivadas.A property overriding a virtual property can also be sealed, specifying that for derived classes it is no longer virtual. Por fim, uma propriedade pode ser declarada abstract.Lastly, a property can be declared abstract. Isso significa que não há nenhuma implementação na classe e as classes derivadas devem escrever sua própria implementação.This means that there is no implementation in the class, and derived classes must write their own implementation. Para obter mais informações sobre essas opções, consulte Classes e membros de classes abstract e sealed.For more information about these options, see Abstract and Sealed Classes and Class Members.

Observação

É um erro usar um modificador virtual, abstract ou override em um acessador de uma propriedade static.It is an error to use a virtual, abstract, or override modifier on an accessor of a static property.

ExemploExample

Este exemplo demonstra as propriedades instância, estática e somente leitura.This example demonstrates instance, static, and read-only properties. Ele aceita o nome do funcionário digitado no teclado, incrementa NumberOfEmployees em 1 e exibe o nome e o número do funcionário.It accepts the name of the employee from the keyboard, increments NumberOfEmployees by 1, and displays the Employee name and number.

public class Employee
{
    public static int NumberOfEmployees;
    private static int _counter;
    private string _name;

    // A read-write instance property:
    public string Name
    {
        get => _name;
        set => _name = value;
    }

    // A read-only static property:
    public static int Counter => _counter;

    // A Constructor:
    public Employee() => _counter = ++NumberOfEmployees; // Calculate the employee's number:
}

class TestEmployee
{
    static void Main()
    {
        Employee.NumberOfEmployees = 107;
        Employee e1 = new Employee();
        e1.Name = "Claude Vige";

        System.Console.WriteLine("Employee number: {0}", Employee.Counter);
        System.Console.WriteLine("Employee name: {0}", e1.Name);
    }
}
/* Output:
    Employee number: 108
    Employee name: Claude Vige
*/

ExemploExample

Este exemplo demonstra como acessar uma propriedade em uma classe base que está escondida por outra propriedade que tenha o mesmo nome em uma classe derivada:This example demonstrates how to access a property in a base class that is hidden by another property that has the same name in a derived class:

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

public class Manager : Employee
{
    private string _name;

    // Notice the use of the new modifier:
    public new string Name
    {
        get => _name;
        set => _name = value + ", Manager";
    }
}

class TestHiding
{
    static void Main()
    {
        Manager m1 = new Manager();

        // Derived class property.
        m1.Name = "John";

        // Base class property.
        ((Employee)m1).Name = "Mary";

        System.Console.WriteLine("Name in the derived class is: {0}", m1.Name);
        System.Console.WriteLine("Name in the base class is: {0}", ((Employee)m1).Name);
    }
}
/* Output:
    Name in the derived class is: John, Manager
    Name in the base class is: Mary
*/

A seguir estão os pontos importantes do exemplo anterior:The following are important points in the previous example:

  • A propriedade Name na classe derivada oculta a propriedade Name na classe base.The property Name in the derived class hides the property Name in the base class. Nesse caso, o modificador new é usado na declaração da propriedade na classe derivada:In such a case, the new modifier is used in the declaration of the property in the derived class:

    public new string Name
    
  • A conversão (Employee) é usada para acessar a propriedade oculta na classe base:The cast (Employee) is used to access the hidden property in the base class:

    ((Employee)m1).Name = "Mary";
    

    Para obter mais informações sobre como ocultar membros, consulte o Modificador new.For more information about hiding members, see the new Modifier.

ExemploExample

Neste exemplo, duas classes, Cube e Square, implementam uma classe abstrata Shape e substituem sua propriedade Area abstrata.In this example, two classes, Cube and Square, implement an abstract class, Shape, and override its abstract Area property. Observe o uso do modificador override nas propriedades.Note the use of the override modifier on the properties. O programa aceita o lado como uma entrada e calcula as áreas para o cubo e o quadrado.The program accepts the side as an input and calculates the areas for the square and cube. Ele também aceita a área como uma entrada e calcula o lado correspondente para o cubo e o quadrado.It also accepts the area as an input and calculates the corresponding side for the square and cube.

abstract class Shape
{
    public abstract double Area
    {
        get;
        set;
    }
}

class Square : Shape
{
    public double side;

    //constructor
    public Square(double s) => side = s;

    public override double Area
    {
        get => side * side;
        set => side = System.Math.Sqrt(value);
    }
}

class Cube : Shape
{
    public double side;

    //constructor
    public Cube(double s) => side = s;

    public override double Area
    {
        get => 6 * side * side;
        set => side = System.Math.Sqrt(value / 6);
    }
}

class TestShapes
{
    static void Main()
    {
        // Input the side:
        System.Console.Write("Enter the side: ");
        double side = double.Parse(System.Console.ReadLine());

        // Compute the areas:
        Square s = new Square(side);
        Cube c = new Cube(side);

        // Display the results:
        System.Console.WriteLine("Area of the square = {0:F2}", s.Area);
        System.Console.WriteLine("Area of the cube = {0:F2}", c.Area);
        System.Console.WriteLine();

        // Input the area:
        System.Console.Write("Enter the area: ");
        double area = double.Parse(System.Console.ReadLine());

        // Compute the sides:
        s.Area = area;
        c.Area = area;

        // Display the results:
        System.Console.WriteLine("Side of the square = {0:F2}", s.side);
        System.Console.WriteLine("Side of the cube = {0:F2}", c.side);
    }
}
/* Example Output:
    Enter the side: 4
    Area of the square = 16.00
    Area of the cube = 96.00

    Enter the area: 24
    Side of the square = 4.90
    Side of the cube = 2.00
*/

Confira tambémSee also