generate - remarks c#




¿Cuándo tiene sentido utilizar un campo público? (7)

La mejor práctica en Java y C # ha sido durante mucho tiempo usar los métodos de obtención / configuración o propiedades para acceder a los campos.

Creo que ese es el primer problema: la idea de que si tienes un captador también debes tener un setter. Esto es un error; en muchos casos, un definidor no es necesario porque no hay una necesidad real de modificar el valor del atributo de un objeto, y eliminar la posibilidad simplifica la clase.

Los casos extremos es no tener mutadores en absoluto. La etapa final para hacer que la clase sea inmutable nunca es hacer que los valores de campo mutables (recuerde, Java final no es como C ++ const ) directamente accesible. Y las clases de pequeño valor deberían ser inmutables. Solo un método de obtención puede proporcionar acceso seguro a campos potencialmente mutables, mediante la creación de una copia (en C ++, simplemente tiene una obtención que devuelve por valor). Podría prescindir del getter para aquellos campos que no requieren copia defensiva, pero algunos campos de una clase pueden requerir un getter y otros no. Pero eso sería confuso,

Esta es una pregunta que he tenido desde hace un tiempo:

¿Cuándo tiene sentido exponer públicamente un campo así?

public class SomeClass()
{
   public int backing;
}

La desventaja de hacer esto (además de enfurecer a los elitistas de POO) es que tiene que introducir un cambio de ruptura en su API si alguna vez necesita agregar alguna lógica a estos datos. Supongo que de eso se tratan los elitistas.

La mejor práctica en Java y C # ha sido durante mucho tiempo usar los métodos de obtención / configuración o propiedades para acceder a los campos.

public class SomeClass()
{
   private int backing;

   public int getBacking()
   {
      return backing;
   }

   public void setBacking(int v)
   {
      backing = v;
   }
}

C # ha evolucionado esto a una sintaxis bastante simple con propiedades automáticas:

public class SomeClass()
{
   public int Backing { get; set; }
}

Lazy me sigue sintiendo que esto es demasiado largo ya que es algo que me encuentro haciendo mucho. Más importante aún, no estoy seguro de saber dónde tendría más sentido un campo público.

¿Por qué no tratar los campos declarados públicamente como propiedades (o métodos) detrás de escena? De esa manera sería imposible enojar a los dioses y disociarlos un poco menos.

public class SomeClass()
{
   public int backing;   // The same as public int backing { get; set; }
}

Para una propiedad que no hace nada más que envolver el campo subyacente, estoy bastante seguro de que el JIT optimiza las llamadas al método, por lo que el rendimiento probablemente no sea el problema. ¿Alguna idea? (aparte de la convención de caso adecuada para el nombre de campo)

EDIT: Gracias por todas las respuestas. Siento que tal vez no todos están entendiendo mi pregunta. ¿Cuándo sería un campo público una mejor opción que una propiedad? ¿Por qué es una mejor opción? Si la única razón es la conveniencia (menos la escritura y el desorden), entonces, ¿cuál sería el inconveniente de que el compilador genere una propiedad "debajo del capó" cuando se encuentre un campo público? Básicamente, sería imposible crear un verdadero campo público (porque todos serían propiedades). ¿Qué estaría mal con eso? Gracias.


¿Cuándo tiene sentido exponer un campo públicamente?

Entre otros lugares, en clases privadas como a continuación.

public class MyOuterClass
{
      private class MyInnerClass
      {
            public int val ; // why bother w/boiler plate
      }
}

Así que la mejor respuesta que puedo dar es que cuando haces magia a través de la reflexión, como se suele hacer cuando se aprovecha un lenguaje estático, las propiedades tienen un significado sobre los campos. Desde elementos como las herramientas de ORM, los mapeadores y los datos de enlace, las propiedades pueden tener un significado diferente al de los campos desde ese punto de vista de comportamiento.

El JITter no convierte las propiedades en campos, puede alinearlas, aunque no prometo que lo haga en todos los casos.


Creo que tiene sentido cuando quieres agrupar algunas variables / objetos (algo así como una struct C). Por ejemplo:

class Pixel {
  public int x;
  public int y;
  Color c;
  // Other Pixel related information
}

Como no hay métodos, nada se rompe si se usa un valor incorrecto y combina muy bien estas variables.


En mi opinión, cuando diseñas una estructura de una clase, debes prestar más atención a los cambios futuros y siempre debes ser amigable con ellos. Si un requisito futuro necesita que hagas algo de lógica antes de devolver un valor en lugar de devolver el valor del campo, deberás cambiar la interfaz de la clase y todos los usuarios de tu biblioteca tendrán que cambiar. Eso suele convertirse en un desastre.

Tenga en cuenta, el principio de apertura / cierre .


Puede usar, en java, un campo público, y luego agregarle algo de lógica, como si hubiera un captador, usando AspectJ, incluyendo evitar escribir en él si no es de un psckage específico, etc.

Si bien esta es una mejora importante, que acelera la codificación y aún deja mucho espacio para futuras mejoras sin que todos tengan que volver a escribir todo su código, no se usa mucho, porque los elitistas son notoriamente fanáticos.

Volviendo a su pregunta, dado que no hay una gran mejora en el uso de campos públicos en lugar de en los buscadores / definidores, y dado que los IDE tienen una generación automática de captadores y definidores, no hay una sobrecarga real de programador en el uso de captadores y definidores. En años de programación en Java, he usado campos públicos solo un par de veces, y siempre terminé convirtiéndolos en pares getters / setters.


Uno de los escenarios en los que el campo público es una mejor opción es proporcionar constantes de su clase.

Por ejemplo, ver:

public const double PI

definido en System.Math.

Este enfoque se ve favorecido porque informa explícitamente a los consumidores de su clase, que este miembro no incluye ninguna lógica, validación ni ninguna otra operación relacionada con el estado, por lo que puede usarse en el contexto que desee.

El otro en el que puedo pensar es cuando necesita clases como contenedores para operaciones simples (o simplemente para pasar la gran cantidad de parámetros a un método), como ejemplo, vea System.Windows.Point . En la mayoría de los casos, estos contenedores están modelados como estructuras sin embargo.





design-patterns