Partilhar via


Restringindo a acessibilidade do acessador (Guia de Programação em C#)

As partes get e set de uma propriedade ou indexador são chamadas acessores. Por padrão, esses acessadores têm a mesma visibilidade ou nível de acesso da propriedade ou indexador ao qual pertencem. Para obter mais informações, consulte Níveis de acessibilidade. No entanto, às vezes é útil restringir o acesso a um desses acessadores. Normalmente, restringe a acessibilidade do acessador set, mantendo o acessador get acessível de forma pública. Por exemplo:

private string _name = "Hello";

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

Neste exemplo, uma propriedade chamada Name define um get e set accessor. O get acessador recebe o nível de acessibilidade da própria propriedade, public neste caso, enquanto o set acessador é explicitamente restrito pela aplicação do modificador de acesso protegido ao próprio acessador.

Nota

Os exemplos neste artigo não usam propriedades implementadas automaticamente. As propriedades implementadas automaticamente fornecem uma sintaxe concisa para declarar propriedades quando um campo de suporte personalizado não é necessário.

Restrições sobre modificadores de acesso em acessadores

O uso dos modificadores de acesso em propriedades ou indexadores está sujeito às seguintes condições:

  • Não é possível usar modificadores de acesso numa interface ou numa implementação explícita de membro de interface.
  • Você pode usar modificadores de acessador apenas se a propriedade ou indexador tiverem ambos os acessadores set e get. Neste caso, o modificador é permitido em apenas um dos dois acessores.
  • Se a propriedade ou indexador tiver um modificador de substituição , o modificador de acessador deverá corresponder ao acessador do acessador substituído, se houver.
  • O nível de acessibilidade no acessador deve ser mais restritivo do que o nível de acessibilidade da propriedade ou do indexador.

Modificadores de acesso na substituição de acessadores

Quando se substitui uma propriedade ou indexador, os acessadores substituídos devem estar acessíveis ao código que faz a substituição. Além disso, a acessibilidade da propriedade/o indexador e os seus métodos de acesso devem corresponder à propriedade/o indexador sobreposto correspondente e os seus métodos de acesso. Por exemplo:

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

Implementação de interfaces

Quando você usa um acessador para implementar uma interface, o acessador pode não ter um modificador de acesso. No entanto, se você implementar a interface usando um acessador, como get, o outro acessador pode ter um modificador de acesso, como no exemplo a seguir:

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 acessador

Se você usar um modificador de acesso no acessador, o domínio de acessibilidade do acessador será determinado por esse modificador.

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 indexador.

Exemplo

O exemplo a seguir contém três classes, BaseClass, DerivedClass, e MainClass. Há duas propriedades no BaseClass, Name e Id em ambas as classes. O exemplo demonstra como a propriedade Id em DerivedClass pode ser ocultada pela propriedade Id quando BaseClass você usa um modificador de acesso restritivo, como protegido ou privado. Portanto, quando você atribui valores a essa propriedade, a propriedade na BaseClass classe é chamada em vez disso. A substituição do modificador de acesso por público tornará a propriedade acessível.

O exemplo também demonstra que um modificador de acesso restritivo, como private ou protected, no acessador da propriedade set em Name impede o acesso ao acessador na classe derivada DerivedClass. Gera um erro quando se atribui a ela, ou acede à propriedade da classe base com o mesmo nome, se estiver acessível.

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ários

Observe que, se você substituir a declaração new private string Id por new public string Id, obterá a saída:

Name and ID in the base class: Name-BaseClass, ID-BaseClass Name and ID in the derived class: John, John123

Consulte também