Restringindo a acessibilidade do acessador (Guia de Programação em C#)
As partes get e set de uma propriedade ou indexador são chamadas de acessadores. 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, você restringe set
a acessibilidade do acessador, mantendo 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
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 em uma interface ou em uma implementação explícita de membro da interface .
- Você pode usar modificadores de acessador somente se a propriedade ou indexador tiver ambos e
set
get
acessadores. Neste caso, o modificador é permitido em apenas um dos dois acessórios. - 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 na própria propriedade ou indexador.
Modificadores de acesso na substituição de acessadores
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 deve corresponder à propriedade/indexador substituída correspondente 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; }
}
}
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 , no set
acessador da Name
propriedade em DerivedClass
impede o acesso ao acessador na protected
classe derivada. Ele gera um erro quando você atribui a ele, ou acessa a propriedade de classe base do 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