En realidad la definición de una
propiedad con la sintaxis antes vista es convertida por el compilador en la
definición de un par de métodos de la siguiente forma:
<tipoPropiedad> get_<nombrePropiedad>()
{ // Método en que se convierte el bloque get
<códigoLectura>
}
void set_<nombrePropiedad> (<tipoPropiedad> value)
{ // Método en que se convierte el bloque set
<códigoEscritura>
}
Esto se hace para que desde
lenguajes que no soporten las propiedades se pueda acceder también a ellas. Si
una propiedad es de sólo lectura sólo se generará el método get_X(),
y si es de sólo escritura sólo se generará el set_X() Ahora bien, en
cualquier caso hay que tener cuidado con no definir en un mismo tipo de dato métodos
con signaturas como estas si se van a generar internamente debido a la
definición de una propiedad, ya que ello provocaría un error de definición
múltiple de método.
Teniendo en cuenta la
implementación interna de las propiedades, es fácil ver que el último ejemplo
de acceso a propiedad es equivalente a:
B b =
new B();
obj.set_PropiedadEjemplo(obj.get_Propiedad_Ejemplo()++);
Como se ve, gracias a las
propiedades se tiene una sintaxis mucho más compacta y clara para acceder a
campos de manera controlada. Se podría pensar que la contrapartida de esto es
que el tiempo de acceso al campo aumenta considerablemente por perderse tiempo
en hacer las llamada a métodos set/get. Pues bien, esto no tiene porqué ser así ya
que el compilador de C# elimina llamadas haciendo inlining (sustitución de la llamada por su cuerpo) en los accesos a
bloques get/set
no virtuales y de códigos pequeños, que son los más habituales.
Nótese que de la forma en que se
definen los métodos generados por el compilador se puede deducir el porqué del hecho de que en el bloque set
se pueda acceder a través de value al valor asignado y de que el objeto
devuelto por el código de un bloque get tenga que ser del mismo tipo de dato que la
propiedad a la que pertenece.