¿En qué situación debo usar un conjunto privado en una propiedad en lugar de convertirla en una propiedad de solo lectura? Tenga en cuenta los dos ejemplos muy simplistas a continuación.
Primer ejemplo:
Public Class Person
Private _name As String
Public Property Name As String
Get
Return _name
End Get
Private Set(ByVal value As String)
_name = value
End Set
End Property
Public Sub WorkOnName()
Dim txtInfo As TextInfo = _
Threading.Thread.CurrentThread.CurrentCulture.TextInfo
Me.Name = txtInfo.ToTitleCase(Me.Name)
End Sub
End Class
// ----------
public class Person
{
private string _name;
public string Name
{
get { return _name; }
private set { _name = value; }
}
public void WorkOnName()
{
TextInfo txtInfo = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo;
this.Name = txtInfo.ToTitleCase(this.Name);
}
}
Segundo ejemplo
Public Class AnotherPerson
Private _name As String
Public ReadOnly Property Name As String
Get
Return _name
End Get
End Property
Public Sub WorkOnName()
Dim txtInfo As TextInfo = _
Threading.Thread.CurrentThread.CurrentCulture.TextInfo
_name = txtInfo.ToTitleCase(_name)
End Sub
End Class
// ---------------
public class AnotherPerson
{
private string _name;
public string Name
{
get { return _name; }
}
public void WorkOnName()
{
TextInfo txtInfo = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo;
_name = txtInfo.ToTitleCase(_name);
}
}
Ambos producen los mismos resultados. ¿Es esta una situación en la que no hay bien ni mal, y es solo una cuestión de preferencia?
public string Name { get; protected set; }
a través de la herencia.Respuestas:
Hay un par de razones para usar
private set
.1) Si no está utilizando un campo de respaldo y desea una propiedad automática de solo lectura:
2) Si desea hacer un trabajo extra cuando modifica la variable dentro de su clase y desea capturarla en una sola ubicación:
En general, sin embargo, es una cuestión de preferencia personal. Hasta donde sé, no hay razones de rendimiento para usar una sobre la otra.
fuente
private set
. :-)public string Name { get; }
. Si no desea una propiedad mutable, esa es la sintaxis preferida ahora.private set
es que no es tan inmutable como nos gusta pretender que lo es. Si desea implementar una clase verdaderamente inmutable, solo lectura es imprescindible.Utilice el conjunto privado cuando desee que no se pueda acceder al configurador desde afuera .
Use solo lectura cuando desee establecer la propiedad solo una vez . En el constructor o inicializador variable.
PRUEBE ESTO:
fuente
readonly
palabra clave C # es aplicarReadOnly
al campo en lugar de a la propiedad.¿Puedo sugerir una tercera opción?
Esto hace que la propiedad Name sea de solo lectura efectiva para todo el código externo y proporciona un método Set explícito. Prefiero el conjunto explícito en lugar de simplemente usar el conjunto en la propiedad Nombre porque está cambiando el valor al configurarlo. Normalmente, si establece un valor de propiedad, espera recuperar el mismo valor cuando llame a get más adelante, lo que no sucedería si hiciera su ToTitleCase en el conjunto .
Sin embargo, como dijiste, no hay una respuesta correcta.
fuente
A partir de C # 6.0, las propiedades automáticas solo para captadores se han agregado al lenguaje. Ver aquí: https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#getter-only-auto-properties .
Aquí hay un ejemplo:
fuente
No uses el segundo ejemplo. El objetivo de usar una propiedad, incluso si no sucede nada más allá de la obtención y la configuración del configurador, es canalizar todo el acceso a través de ese getter y setter para que si alguna vez necesita cambiar el comportamiento en el futuro, todo esté en un lugar.
Su segundo ejemplo lo abandona en el caso de establecer la propiedad. Si utilizó ese enfoque en una clase grande y compleja, y luego necesitó cambiar el comportamiento de la propiedad, estaría en la búsqueda y reemplazo de tierras, en lugar de hacer el cambio en un lugar: el setter privado.
fuente
Siempre que necesité cambiar el nivel de acceso de un setter, generalmente lo cambié a Protegido (solo esta clase y las clases derivadas pueden cambiar el valor) o Amigo (solo los miembros de mi asamblea pueden cambiar el valor).
Pero usar Private tiene mucho sentido cuando quieres hacer otras tareas en el setter además de cambiar el valor de respaldo. Como se señaló anteriormente, es un buen diseño no hacer referencia a sus valores de respaldo directamente, sino solo acceder a ellos a través de sus propiedades. Eso garantiza que los cambios posteriores que realice en una propiedad se apliquen tanto interna como externamente. Y prácticamente no hay penalización de rendimiento al hacer referencia a una propiedad frente a su variable de respaldo.
fuente
Pero para aclarar, acceder a una propiedad es más lento que acceder a su variable de respaldo. El captador y definidor de una propiedad son métodos que requieren una Llamada y un Retorno, mientras que se accede directamente a la variable de respaldo de una propiedad.
Es por eso que, en los casos en que se puede acceder al captador de una propiedad muchas veces dentro de un bloque de código, el valor de la propiedad a veces se almacena primero en caché (se guarda en una variable local) y se usa la variable local en su lugar. Por supuesto, eso supone que la propiedad no se puede cambiar de forma asincrónica mientras se ejecuta el bloque.
fuente