Estoy tomando una clase de C # en este momento y estoy tratando de encontrar la mejor manera de hacer las cosas. Vengo de una experiencia en Java, por lo que solo estoy familiarizado con las mejores prácticas de Java; ¡Soy un novato en C #!
En Java, si tengo una propiedad privada, hago esto;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
En C #, veo que hay muchas formas de hacer esto.
Puedo hacerlo como Java:
private string name;
public void setName(string name) {
this.name = name;
}
public string getName() {
return this.name;
}
O puedo hacerlo de esta manera:
private string name;
public string Name {
get { return name; }
set { name = value; }
}
O:
public string Name { get; set; }
¿Cuál debería usar y cuáles son las advertencias o sutilezas involucradas con cada enfoque? Al crear clases, sigo las mejores prácticas generales que conozco de Java (especialmente leyendo Effective Java). Entonces, por ejemplo, estoy favoreciendo la inmutabilidad (proporcionando setters solo cuando sea necesario). Solo tengo curiosidad por ver cómo encajan estas prácticas con las diversas formas de proporcionar setters y getters en C #; esencialmente, ¿cómo traduciría las mejores prácticas del mundo de Java a C #?
EDITAR
Estaba publicando esto como un comentario a la respuesta de Jon Skeet, pero luego se hizo largo:
¿Qué pasa con una propiedad no trivial (es decir, con un procesamiento y validación significativos tal vez)? ¿Podría todavía exponerlo a través de una propiedad pública pero con la lógica encapsulada en get
y set
? ¿Por qué debería / debería hacer esto en lugar de tener métodos de establecimiento y obtención dedicados (con procesamiento asociado y lógica de validación)?
fuente
public int Y { get; } = y;
).Si todo lo que necesita es una variable para almacenar algunos datos:
¿Quieres que parezca de solo lectura?
O mejor...
¿Quiere comprobar el valor antes de asignar la propiedad?
En general, GetXyz () y SetXyz () solo se usan en ciertos casos, y solo tiene que usar su instinto cuando se sienta bien. En general, diría que espero que la mayoría de las propiedades get / set no contengan mucha lógica y tengan muy pocos efectos secundarios inesperados, si es que tienen alguno. Si leer el valor de una propiedad requiere invocar un servicio o obtener información de un usuario para construir el objeto que estoy solicitando, entonces lo envolvería en un método y lo llamaría algo como
BuildXyz()
, en lugar deGetXyz()
.fuente
myList.Add()
, por ejemplo (siempre que el objeto esté expuesto a cambios, es mutable).Min
/Max
? ¿Quiere asegurarse de esoMax > Min
? Tener unSetRange(Min, Max)
podría tener sentido, pero entonces, ¿cómo vas a leer esos valores? ¿Propiedades mínimas / máximas de solo lectura? Lanzar excepciones para entradas no válidas parece ser la forma más limpia de manejar esto.Use propiedades en C #, no métodos get / set. Están ahí para su conveniencia y es idiomático.
En cuanto a sus dos ejemplos de C #, uno es simplemente azúcar sintáctico para el otro. Use la propiedad auto si todo lo que necesita es un contenedor simple alrededor de una variable de instancia, use la versión completa cuando necesite agregar lógica en el getter y / o setter.
fuente
En C # favorece las propiedades para exponer campos privados para get y / o set. La forma que mencionas es una propiedad automática en la que get y set generan automáticamente un campo de respaldo de pivote oculto para ti.
Prefiero las propiedades automáticas cuando sea posible, pero nunca debe hacer un par de métodos set / get en C #.
fuente
Esta es simplemente una propiedad implementada automáticamente y técnicamente es lo mismo que una propiedad normal. Se creará un campo de respaldo al compilar.
Todas las propiedades se convierten eventualmente en funciones, por lo que la implementación compilada real al final es la misma a la que está acostumbrado en Java.
Utilice propiedades implementadas automáticamente cuando no tenga que realizar operaciones específicas en el campo de respaldo. Utilice una propiedad ordinaria de lo contrario. Use las funciones get y set cuando la operación tenga efectos secundarios o sea computacionalmente costosa, use propiedades de lo contrario.
fuente
Independientemente de la forma que elija en C #, el resultado final es el mismo. Obtendrá una variable backinng con métodos getter y setter separados. Al usar propiedades, está siguiendo las mejores prácticas y, por lo tanto, es una cuestión de cuán detallado desea obtener.
Personalmente elegiría auto-propiedades, la última versión:,
public string Name { get; set; }
ya que ocupan la menor cantidad de espacio. Y siempre puede expandirlos en el futuro si necesita agregar algo como validación.fuente
Siempre que sea posible, prefiero el público,
string Name { get; set; }
ya que es conciso y fácil de leer. Sin embargo, puede haber ocasiones en las que este sea necesariofuente
En C #, la forma preferida es a través de propiedades en lugar de métodos
getX()
ysetX()
. Además, tenga en cuenta que C # no requiere que las propiedades tengan tanto un get como un set; puede tener propiedades de solo get y propiedades de solo set.fuente
Primero déjame intentar explicarte lo que escribiste:
Esta estructura también se usa hoy en día, pero es más adecuada si desea hacer alguna funcionalidad adicional, por ejemplo, cuando se establece un valor, puede analizarlo para capitalizarlo y guardarlo en un miembro privado para modificar el uso interno.
Con .net framework 3.0
Te deseo mejor suerte en C #
fuente
Como se mencionó, todos estos enfoques dan como resultado el mismo resultado. Lo más importante es que elija una convención y se ciña a ella. Prefiero usar los dos últimos ejemplos de propiedades.
fuente
como la mayoría de las respuestas aquí, use propiedades automáticas. Intuitivo, menos líneas de código y más limpio. Si debe serializar su clase, marque la clase
[Serializable]
/ con el[DataConract]
atributo. Y si está utilizando,[DataContract]
marque el miembro conEl setter privado o público depende de su preferencia.
También tenga en cuenta que las propiedades automáticas requieren captadores y definidores (públicos o privados).
Alternativamente, si solo desea obtener / configurar, cree un campo de respaldo usted mismo
fuente
Cuando se trata de propiedades, hay una advertencia que aún no se ha mencionado: con propiedades no puede tener ninguna parametrización de sus getters o setters.
Por ejemplo, imagine que desea recuperar los elementos de una lista y también desea aplicar un filtro al mismo tiempo. Con un método de obtención, podría escribir algo como:
Por el contrario, con una propiedad está obligado a devolver primero todos los artículos
y luego aplique el filtro en el siguiente paso o tiene que agregar propiedades dedicadas que exponen elementos filtrados por diferentes criterios, lo que pronto hincha su API:
Lo que a veces puede ser una molestia es cuando comenzó con una propiedad, por ejemplo,
obj.items
y luego descubrió que se necesita una parametrización de getter o setter o que facilitaría las cosas para el usuario de la API de clase. Ahora necesitaría reescribir su API y modificar todos esos lugares en su código que acceden a esta propiedad o encontrar una solución alternativa. Por el contrario, con un método get, por ejemploobj.getItems()
, puede simplemente extender la firma de su método para aceptar un objeto de "configuración" opcional, por ejemploobj.getItems(options)
sin tener que reescribir todos esos lugares que llaman a su método.Dicho esto, las propiedades (implementadas automáticamente) en C # siguen siendo atajos muy útiles (por las diversas razones mencionadas aquí) ya que la mayoría de las veces la parametrización puede no ser necesaria, pero esta advertencia se mantiene.
fuente