Limitazione dell'accessibilità delle funzioni di accesso (Guida per programmatori C#)
Le parti get e set di una proprietà o di un indicizzatore sono denominate funzioni di accesso. Per impostazione predefinita, queste funzioni di accesso hanno la stessa visibilità, ovvero livello di accesso, della proprietà o dell'indicizzatore cui appartengono. Per ulteriori informazioni, vedere Livelli di accessibilità. Risulta tuttavia utile a volte limitare l'accesso a una di queste funzioni di accesso. In genere, ciò implica la restrizione dell'accessibilità della funzione di accesso set, mantenendo pubblicamente accessibile la funzione di accesso get. Di seguito è riportato un esempio:
private string name = "Hello";
public string Name
{
get
{
return name;
}
protected set
{
name = value;
}
}
In questo esempio una proprietà denominata Name definisce le funzioni di accesso get e set. La funzione di accesso get riceve il livello di accessibilità della proprietà stessa, in questo caso public, mentre la funzione di accesso set viene limitata in modo esplicito applicando il modificatore di accesso protected.
Restrizioni dei modificatori di accesso sulle funzioni di accesso
L'utilizzo dei modificatori delle funzioni di accesso per le proprietà o gli indicizzatori è soggetto alle seguenti condizioni:
Non è possibile utilizzare i modificatori delle funzioni di accesso su un'interfaccia o su un'implementazione esplicita di un membro di interfaccia.
È possibile utilizzare i modificatori delle funzioni di accesso solo se la proprietà o l'indicizzatore contiene entrambe le funzioni di accesso set e get. In questo caso, il modificatore è consentito solo per una delle due funzioni di accesso.
Se la proprietà o l'indicizzatore contiene un modificatore override, il modificatore della funzione di accesso deve corrispondere alla funzione di accesso dell'eventuale funzione di accesso di cui è stato eseguito l'override.
Il livello di accessibilità per la funzione di accesso deve essere più restrittivo di quello per la proprietà o per l'indicizzatore.
Modificatori di accesso per le funzioni di accesso di override
Quando si esegue l'override di una proprietà o di un indicizzatore, le funzioni di accesso sottoposte a override devono essere accessibili per il codice di override. Il livello di accessibilità della proprietà/indicizzatore e delle funzioni di accesso deve essere uguale a quello delle corrispondenti proprietà/indicizzatore e funzioni di accesso sottoposte a override. Di seguito è riportato un esempio:
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; }
}
}
Implementazione di interfacce
Se utilizzata per implementare un'interfaccia, una funzione di accesso non può contenere un modificatore di accesso. Se tuttavia l'interfaccia viene implementata utilizzando un'unica funzione di accesso, ad esempio get, l'altra funzione di accesso può contenere un modificatore, come illustrato nell'esempio seguente:
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 { }
}
}
Dominio di accessibilità delle funzioni di accesso
Se per la funzione di accesso si utilizza un modificatore di accesso, il dominio di accessibilità di tale funzione è determinato da questo modificatore.
Se per la funzione di accesso non si utilizza alcun modificatore di accesso, il dominio di accessibilità della funzione è determinato dal livello di accessibilità della proprietà o dell'indicizzatore.
Esempio
Nell'esempio seguente sono riportate tre classi, ovvero BaseClass, DerivedClass e MainClass. La classe BaseClass contiene due proprietà, Name e Id in entrambe le classi. Nell'esempio viene dimostrato che la proprietà Id della classe DerivedClass può essere nascosta dalla proprietà Id della classe BaseClass quando si utilizza un modificatore di accesso restrittivo come protected o private. Di conseguenza, quando si assegnano valori a questa proprietà, viene invece chiamata la proprietà della classe BaseClass. Se il modificatore di accesso viene sostituito con public, la proprietà diventerà accessibile.
Nell'esempio viene inoltre dimostrato che un modificatore di accesso restrittivo, ad esempio private o protected, per la funzione di accesso set della proprietà Name nella classe DerivedClass impedisce l'accesso alla funzione di accesso e genera un errore quando vengono assegnati i valori.
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
*/
Commenti
Se la dichiarazione new private string Id viene sostituita con new public string Id, si otterrà l'output:
Name and ID in the base class: Name-BaseClass, ID-BaseClass
Name and ID in the derived class: John, John123
Vedere anche
Riferimenti
Proprietà (Guida per programmatori C#)
Indicizzatori (Guida per programmatori C#)
Modificatori di accesso (Guida per programmatori C#)