Accesibilidad del descriptor de acceso asimétrico (Guía de programación de C#)
Actualización: noviembre 2007
Las partes get y set de una propiedad o indizador se denominan descriptores de acceso. De forma predeterminada estos descriptores de acceso tienen la misma visibilidad o nivel de acceso: el de la propiedad o indizador al que pertenecen. Para obtener más información, vea Niveles de accesibilidad. Sin embargo, es a veces útil para restringir el acceso a uno de estos descriptores de acceso. Normalmente, esto implica restringir la accesibilidad del descriptor de acceso set, al mismo tiempo que el descriptor de acceso get se mantiene públicamente accesible. Por ejemplo:
private string name = "Hello";
public string Name
{
get
{
return name;
}
protected set
{
name = value;
}
}
En este ejemplo, una propiedad denominada Name define un descriptor de acceso get y set. El descriptor de acceso get recibe el nivel de accesibilidad de la misma propiedad, public en este caso, al mismo tiempo que el descriptor de acceso set se restringe explícitamente aplicando el modificador de acceso protected al propio descriptor de acceso.
Restricciones en los modificadores y descriptores de acceso
El uso de modificadores de descriptores de acceso en propiedades o indizadores está sujeto a estas condiciones:
No se pueden utilizar modificadores de descriptores de acceso en una interfaz o en una implementación explícita de miembro de interface.
Sólo se pueden utilizar los modificadores de descriptores de acceso si la propiedad o el indizador tiene descriptores de acceso set y get. En este caso, sólo se permite el modificador en sólo uno de los dos descriptores de acceso.
Si la propiedad o el indizador tiene un modificador override, el modificador del descriptor de acceso debe coincidir con el descriptor de acceso del descriptor de acceso de reemplazo, si corresponde.
El nivel de accesibilidad en el descriptor de acceso debe ser más restrictivo que el nivel de accesibilidad en la propiedad o el indizador.
Modificadores de acceso en descriptores de acceso de reemplazo
Cuando se reemplaza una propiedad o un indizador, los descriptores de acceso reemplazados deben ser accesibles al código de reemplazo. Además, el nivel de accesibilidad de la propiedad y del indizador, y de los descriptores de acceso debe coincidir con la propiedad y el indizador reemplazado y los descriptores de acceso correspondientes. Por ejemplo:
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
Cuando utiliza un descriptor de acceso para implementar una interfaz, el descriptor de acceso no puede tener un modificador de acceso. Sin embargo, si implementa la interfaz mediante un descriptor de acceso, como get, el otro descriptor de acceso puede tener un modificador de acceso, como se muestra en el siguiente ejemplo:
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 de accesibilidad del descriptor de acceso
Si utiliza un modificador de acceso en el descriptor de acceso, este modificador determina el dominio de accesibilidad del descriptor de acceso.
Si no se ha utilizado un modificador de acceso en el descriptor de acceso, el dominio de accesibilidad del descriptor de acceso se determina mediante el nivel de accesibilidad de la propiedad o del indizador.
Ejemplo
El siguiente ejemplo contiene tres clases, BaseClass, DerivedClass y MainClass. Hay dos propiedades en BaseClass, Name e Id en ambas clases. El ejemplo muestra cómo la propiedad Id en DerivedClass se puede ocultar a través de la propiedad Id en BaseClass cuando se utiliza un modificador de acceso restrictivo como protected o private. Por consiguiente, cuando asigna valores a esta propiedad, se llama a la propiedad en la clase BaseClass en su lugar. Reemplazar el modificador de acceso a través de public hará que la propiedad sea accesible.
El ejemplo también muestra que un modificador de acceso restrictivo como private o protected, en el descriptor de acceso set de la propiedad Name en DerivedClass impide el acceso al descriptor de acceso y genera un error cuando lo asigna.
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
*/
Comentarios
Observe que si reemplaza la declaración new private string Id por new public string Id, obtiene el resultado:
Name and ID in the base class: Name-BaseClass, ID-BaseClass
Name and ID in the derived class: John, John123
Vea también
Conceptos
Referencia
Propiedades (Guía de programación de C#)