Restringindo a acessibilidade ao acessador (Guia de Programação em C#)Restricting Accessor Accessibility (C# Programming Guide)

As partes get e set de uma propriedade ou de um indexador são chamadas acessadores.The get and set portions of a property or indexer are called accessors. Por padrão, esses acessadores têm a mesma visibilidade ou nível de acesso da propriedade ou do indexador aos quais pertencem.By default these accessors have the same visibility or access level of the property or indexer to which they belong. Para obter mais informações, consulte níveis de acessibilidade.For more information, see accessibility levels. No entanto, às vezes é útil restringir o acesso a um desses acessadores.However, it is sometimes useful to restrict access to one of these accessors. Normalmente, isso envolve restringir a acessibilidade do acessador set e manter o acessador get publicamente acessível.Typically, this involves restricting the accessibility of the set accessor, while keeping the get accessor publicly accessible. Por exemplo: For example:

private string _name = "Hello";

public string Name
{
    get
    {
        return _name;
    }
    protected set
    {
        _name = value;
    }
}

Neste exemplo, uma propriedade chamada Name define um acessador get e set.In this example, a property called Name defines a get and set accessor. O acessador get recebe o nível de acessibilidade da propriedade em si, public nesse caso, embora o set acessador esteja restrito explicitamente ao aplicar o modificador de acesso protegido ao acessador em si.The get accessor receives the accessibility level of the property itself, public in this case, while the set accessor is explicitly restricted by applying the protected access modifier to the accessor itself.

Restrições em modificadores de acesso nos acessadoresRestrictions on Access Modifiers on Accessors

O uso dos modificadores de acesso em propriedades ou indexadores está sujeito a estas condições:Using the accessor modifiers on properties or indexers is subject to these conditions:

  • Não é possível usar os modificadores de acessador em uma interface ou em uma implementação de membro de interface explícita.You cannot use accessor modifiers on an interface or an explicit interface member implementation.

  • É possível usar os modificadores de acessador somente se a propriedade ou o indexador tiver os acessadores set e get.You can use accessor modifiers only if the property or indexer has both set and get accessors. Nesse caso, o modificador é permitido em apenas um dos dois acessadores.In this case, the modifier is permitted on only one of the two accessors.

  • Se a propriedade ou o indexador tiver um modificador substituir, o modificador de acessador deverá corresponder o acessador do acessador substituído, se houver.If the property or indexer has an override modifier, the accessor modifier must match the accessor of the overridden accessor, if any.

  • O nível de acessibilidade do acessador deve ser mais restritivo do que o nível de acessibilidade na propriedade ou no indexador em si.The accessibility level on the accessor must be more restrictive than the accessibility level on the property or indexer itself.

Modificadores de acesso em acessadores de substituiçãoAccess Modifiers on Overriding Accessors

Quando você substitui uma propriedade ou indexador, os acessadores substituídos devem estar acessíveis ao código de substituição.When you override a property or indexer, the overridden accessors must be accessible to the overriding code. Além disso, a acessibilidade da propriedade/indexador, e seus acessadores, devem corresponder à propriedade/indexador substituído e seus acessadores.Also, the accessibility of both the property/indexer and its accessors must match the corresponding overridden property/indexer and its accessors. Por exemplo: For example:

public class Parent
{
    public virtual int TestProperty
    {
        // Notice the accessor accessibility level.
        protected set { }

        // No access modifier is used here.
        get { return 0; }
    }
}
public class Kid : Parent
{
    public override int TestProperty
    {
        // Use the same accessibility level as in the overridden accessor.
        protected set { }

        // Cannot use access modifier here.
        get { return 0; }
    }
}

Implementando interfacesImplementing Interfaces

Quando você usa um acessador para implementar uma interface, o acessador pode não ter um modificador de acesso.When you use an accessor to implement an interface, the accessor may not have an access modifier. No entanto, se você implementar a interface usando um acessador, como get, o outro acessador poderá ter um modificador de acesso, como no exemplo a seguir:However, if you implement the interface using one accessor, such as get, the other accessor can have an access modifier, as in the following example:

public interface ISomeInterface
{
    int TestProperty
    {
        // No access modifier allowed here
        // because this is an interface.
        get;
    }
}

public class TestClass : ISomeInterface
{
    public int TestProperty
    {
        // Cannot use access modifier here because
        // this is an interface implementation.
        get { return 10; }

        // Interface property does not have set accessor,
        // so access modifier is allowed.
        protected set { }
    }
}

Domínio de acessibilidade do acessadorAccessor Accessibility Domain

Se você usar um modificador de acesso no acessador, o domínio de acessibilidade do acessador será determinado por esse modificador.If you use an access modifier on the accessor, the accessibility domain of the accessor is determined by this modifier.

Se você não usou um modificador de acesso no acessador, o domínio de acessibilidade do acessador é determinado pelo nível de acessibilidade da propriedade ou do indexador.If you did not use an access modifier on the accessor, the accessibility domain of the accessor is determined by the accessibility level of the property or indexer.

ExemploExample

O exemplo a seguir contém três classes, BaseClass, DerivedClass e MainClass.The following example contains three classes, BaseClass, DerivedClass, and MainClass. Há duas propriedades no BaseClass, Name e Id em ambas as classes.There are two properties on the BaseClass, Name and Id on both classes. O exemplo demonstra como a propriedade Id no DerivedClass pode ser oculta pela propriedade Id no BaseClass quando você usa um modificador de acesso restritivo como protegido ou privado.The example demonstrates how the property Id on DerivedClass can be hidden by the property Id on BaseClass when you use a restrictive access modifier such as protected or private. Portanto, em vez disso, quando você atribui valores a essa propriedade, a propriedade na classe BaseClass é chamada.Therefore, when you assign values to this property, the property on the BaseClass class is called instead. Substituindo o modificador de acesso por público tornará a propriedade acessível.Replacing the access modifier by public will make the property accessible.

O exemplo também demonstra que um modificador de acesso restritivo, como private ou protected, no acessador set da propriedade Name no DerivedClass impede o acesso ao acessador e gera um erro quando você atribui a ele.The example also demonstrates that a restrictive access modifier, such as private or protected, on the set accessor of the Name property in DerivedClass prevents access to the accessor and generates an error when you assign to it.

public class BaseClass
{
    private string _name = "Name-BaseClass";
    private string _id = "ID-BaseClass";

    public string Name
    {
        get { return _name; }
        set { }
    }

    public string Id
    {
        get { return _id; }
        set { }
    }
}

public class DerivedClass : BaseClass
{
    private string _name = "Name-DerivedClass";
    private string _id = "ID-DerivedClass";

    new public string Name
    {
        get
        {
            return _name;
        }

        // Using "protected" would make the set accessor not accessible.
        set
        {
            _name = value;
        }
    }

    // Using private on the following property hides it in the Main Class.
    // Any assignment to the property will use Id in BaseClass.
    new private string Id
    {
        get
        {
            return _id;
        }
        set
        {
            _id = value;
        }
    }
}

class MainClass
{
    static void Main()
    {
        BaseClass b1 = new BaseClass();
        DerivedClass d1 = new DerivedClass();

        b1.Name = "Mary";
        d1.Name = "John";

        b1.Id = "Mary123";
        d1.Id = "John123";  // The BaseClass.Id property is called.

        System.Console.WriteLine("Base: {0}, {1}", b1.Name, b1.Id);
        System.Console.WriteLine("Derived: {0}, {1}", d1.Name, d1.Id);

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}
/* Output:
    Base: Name-BaseClass, ID-BaseClass
    Derived: John, ID-BaseClass
*/

ComentáriosComments

Observe que, se você substituir a declaração new private string Id por new public string Id, você obterá a saída:Notice that if you replace the declaration new private string Id by new public string Id, you get the output:

Name and ID in the base class: Name-BaseClass, ID-BaseClass

Name and ID in the derived class: John, John123

Confira tambémSee also