Restringindo a acessibilidade aos acessadores (Guia de Programação em C#)

O obter e set são chamados de partes de uma propriedade ou indexador acessadores. Por padrão esses acessadores possuem a mesma visibilidade, ou nível de acesso que da propriedade ou indexador às quais eles pertencem. Para obter mais informações, consulte níveis de acessibilidade. No entanto, às vezes é útil restringir o acesso a um desses acessadores. Normalmente, isso envolve a restringir a acessibilidade da set acessador, e manter o get acessador acessível publicamente. 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 acessador. O get acessador recebe o nível de acessibilidade da propriedade propriamente dito, public nesse caso, enquanto o set acessador explicitamente é restrito, aplicando o protegido modificador de acesso para o acessador propriamente dito.

Restrições sobre os modificadores de acesso nos assessores

Usando os modificadores de assessor em propriedades ou indexadores está sujeita às seguintes condições:

  • Não é possível usar modificadores de assessor em uma interface ou um explícito interface implementação de um membro.

  • Você pode usar modificadores de assessor somente se a propriedade ou indexador tem dois set e get acessadores. Nesse caso, o modificador é permitido em um só os dois acessadores.

  • Se a propriedade ou indexador tiver um Substituir modificador, o modificador de acesso deve coincidir com o acessador do acessador substituído, se houver.

  • O nível de acessibilidade no acessador deve ser mais restritivo que o nível de acessibilidade na propriedade ou indexador propriamente dito.

Modificadores de acesso em substituindo acessadores

Quando você substituir uma propriedade ou indexador, os acessadores substituídos devem ser acessíveis para o código de substituição. Além disso, o nível de acessibilidade de tanto o propriedade/indexador e dos acessadores devem corresponder o propriedade/indexador em correspondente substituído e os acessadores. 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; }
    }
}

Implementar Interfaces

Quando você usa um acessador para implementar uma interface, o acessador não pode ter um modificador de acesso. No entanto, se você implementa a interface usando um acessador, como get, o acessador outro 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 o domínio de acessibilidade do acessador é determinada por esse modificador.

Se você não tiver usado um modificador de acesso em o acessador, 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 sobre o BaseClass, Name e Id em ambas as classes. O exemplo demonstra como a propriedade Id na DerivedClass podem ser ocultados pela propriedade Id na BaseClass quando você usa um modificador de acesso restrito, como protegido ou particular. Portanto, quando você atribuir valores para essa propriedade, a propriedade sobre a BaseClass classe é chamada em vez disso. Substituindo o modificador de acesso por pública fará com que a propriedade acessíveis.

O exemplo também demonstra que um modificador de acesso restritivas, como private ou protecteddiante a set assessor da Name propriedade na DerivedClass impede o acesso para o acessador e gera um erro quando você atribui a ele.

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, você obtém 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

Referência

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

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

Modificadores de acesso (Guia de Programação em C#)

Conceitos

Guia de Programação em C#