Restringindo a acessibilidade ao acessador (Guia de Programação em C#)
As partes get e set de uma propriedade ou de um indexador são chamadas acessadores. Por padrão, esses acessadores têm a mesma visibilidade ou nível de acesso da propriedade ou do indexador aos quais pertencem. Para obter mais informações, consulte níveis de acessibilidade. No entanto, às vezes é útil restringir o acesso a um desses acessadores. Normalmente, você restringe a acessibilidade do acessador set
, mantendo o acessador get
publicamente acessível. Por exemplo:
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
. 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.
Observação
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 em modificadores de acesso nos acessadores
O uso dos modificadores de acesso em propriedades ou indexadores está sujeito a estas condições:
- Não é possível usar modificadores de acessador em uma interface nem uma implementação explícita de membro de interface.
- É possível usar os modificadores de acessador somente se a propriedade ou o indexador tiver os acessadores
set
eget
. Nesse caso, o modificador é permitido em apenas um dos dois acessadores. - Se a propriedade ou o indexador tiver um modificador substituir, o modificador de acessador deverá corresponder o acessador do acessador substituído, se houver.
- 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.
Modificadores de acesso em acessadores de substituição
Quando você substitui uma propriedade ou indexador, os acessadores substituídos devem estar acessíveis ao código de substituição. Além disso, a acessibilidade da propriedade/indexador, e seus acessadores, devem corresponder à propriedade/indexador substituído e seus 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; }
}
}
Implementando 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 poderá 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 será determinado pelo nível de acessibilidade da propriedade ou do 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
no DerivedClass
pode ser oculta pela propriedade Id
no BaseClass
quando você usa um modificador de acesso restritivo como protegido ou privado. Portanto, em vez disso, quando você atribui valores a essa propriedade, a propriedade na classe BaseClass
é chamada. Substituindo o 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 set
da propriedade Name
em DerivedClass
impede o acesso ao acessador na classe derivada. Ele gera um erro quando você faz uma atribuição a ele ou acessa a propriedade de classe base com o mesmo nome, quando 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
, você obterá a saída:
Name and ID in the base class: Name-BaseClass, ID-BaseClass
Name and ID in the derived class: John, John123