Propiedades vs Métodos

Pregunta rápida: ¿Cuándo decide usar las propiedades (en C #) y cuándo decide usar los métodos?

Estamos ocupados teniendo este debate y hemos encontrado algunas áreas donde es discutible si debemos usar una propiedad o un método. Un ejemplo es esto:

public void SetLabel(string text) { Label.Text = text; } 

En el ejemplo, Label es un control en una página ASPX. ¿Hay algún principio que pueda regir la decisión (en este caso) si se trata de un método o una propiedad?

Aceptaré la respuesta más general e integral, pero eso también afecta al ejemplo que he dado.

Desde la sección Elección entre propiedades y métodos de las Pautas de diseño para desarrollar bibliotecas de clases:

En general, los métodos representan acciones y las propiedades representan datos. Las propiedades están destinadas a ser usadas como campos, lo que significa que las propiedades no deben ser computacionalmente complejas o producir efectos secundarios. Cuando no infringe las siguientes pautas, considere usar una propiedad, en lugar de un método, porque los desarrolladores menos experimentados encuentran las propiedades más fáciles de usar.

Sí, si todo lo que hace es obtener y configurar, use una propiedad.

Si está haciendo algo complejo que puede afectar a varios miembros de datos, un método es más apropiado. O si su getter toma parámetros o su setter toma más que un parámetro de valor.

En el medio hay un área gris donde la línea puede estar un poco borrosa. No existe una regla dura y rápida, y diferentes personas a veces no estarán de acuerdo en si algo debe ser una propiedad o un método. Lo importante es ser (relativamente) coherente con la forma en que lo haces (o cómo lo hace tu equipo).

Son en gran medida intercambiables, pero una propiedad le indica al usuario que la implementación es relativamente “simple”. Ah, y la syntax es un poco más limpia.

En términos generales, mi filosofía es que si comienzas a escribir un nombre de método que comienza con get o set y toma cero o un parámetro (respectivamente), entonces es un candidato principal para una propiedad.

Si está configurando una propiedad real de su objeto, entonces usa una propiedad.

Si está realizando una tarea / funcionalidad, entonces usa un método.

En su ejemplo, se está estableciendo una propiedad definitiva.

Sin embargo, si su funcionalidad era AppendToLabel, entonces usaría un método.

Las propiedades son una forma de inyectar o recuperar datos de un objeto. Crean una abstracción sobre variables o datos dentro de una clase. Son análogos a getters y setters en Java.

Los métodos encapsulan una operación.

En general, utilizo propiedades para exponer bits individuales de datos, o pequeños cálculos en una clase, como el impuesto a las ventas. Que se deriva de la cantidad de artículos y su costo en un carrito de compras.

Utilizo métodos cuando creo una operación, como recuperar datos de la base de datos. Cualquier operación que tenga partes móviles, es un candidato para un método.

En su ejemplo de código, lo envolvería en una propiedad si necesito acceder fuera de la clase que contiene:

 public Label Title { get{ return titleLabel;} set{ titleLabel = value;} } 

Configurando el texto:

 Title.Text = "Properties vs Methods"; 

Si solo estuviera configurando la propiedad Text de la Etiqueta, así es como lo haría:

 public string Title { get{ return titleLabel.Text;} set{ titleLabel.Text = value;} } 

Configurando el texto:

 Title = "Properties vs Methods"; 

Solo necesita mirar el mismo nombre … “Propiedad”. Qué significa eso? El diccionario lo define de muchas maneras, pero en este caso “un atributo esencial o distintivo o la calidad de una cosa” encaja mejor.

Piensa en el propósito de la acción. ¿Estás, de hecho, alterando o recuperando “un atributo esencial o distintivo”? En su ejemplo, está usando una función para establecer una propiedad de un cuadro de texto. Eso parece un poco tonto, ¿no?

Las propiedades realmente son funciones. Todos comstackn hasta getXXX () y setXXX (). Simplemente los oculta en azúcar sintáctico, pero es el azúcar el que proporciona un significado semántico al proceso.

Piensa en propiedades como atributos. Un auto tiene muchos atributos. Color, MPG, Modelo, etc. No todas las propiedades son variables, algunas son calculables.

Mientras tanto, un Método es una acción. GetColor debería ser una propiedad. GetFile () debería ser una función. Otra regla general es que, si no cambia el estado del objeto, entonces debería ser una función. Por ejemplo, CalculatePiToNthDigit (n) debería ser una función, porque en realidad no está cambiando el estado del objeto Math al que está conectado.

Esto tal vez divaga un poco, pero realmente se reduce a decidir cuáles son tus objetos y qué representan. Si no puede averiguar si debe ser una propiedad o función, tal vez no importe cuál.

Las propiedades de Symantically son atributos de tus objetos. Los métodos son comportamientos de tu objeto.

La etiqueta es un atributo y tiene más sentido convertirla en una propiedad.

En términos de Progtwigción Orientada a Objetos, debes tener una comprensión clara de qué es parte del comportamiento y qué es meramente un atributo.

Coche {Color, Modelo, Marca}

Un automóvil tiene atributos de Color, Modelo y Marca, por lo que no tiene sentido tener un método SetColor o SetModel porque, de forma simétrica, no le pedimos a Car que establezca su propio color.

Por lo tanto, si asigna el caso de propiedad / método al objeto de la vida real o lo mira desde el punto de vista semántico, su confusión realmente desaparecerá.

Al buscar a través de MSDN, encontré una referencia en Propiedades vs Métodos que proporciona algunas excelentes pautas para crear métodos:

  • La operación es una conversión, como Object.ToString .
  • La operación es lo suficientemente costosa como para querer comunicarle al usuario que debería considerar almacenar el resultado en el caché.
  • Obtener un valor de propiedad usando el acceso de get tendría un efecto secundario observable.
  • Llamar al miembro dos veces seguidas produce resultados diferentes.
  • El orden de ejecución es importante. Tenga en cuenta que las propiedades de un tipo se deben poder establecer y recuperar en cualquier orden.
  • El miembro es estático pero devuelve un valor que se puede cambiar.
  • El miembro devuelve una matriz. Las propiedades que devuelven matrices pueden ser muy engañosas. Por lo general, es necesario devolver una copia de la matriz interna para que el usuario no pueda cambiar el estado interno. Esto, junto con el hecho de que un usuario puede asumir fácilmente que es una propiedad indexada, conduce a un código ineficiente.

Prefiero usar propiedades para los métodos add / set con 1 parámetro. Si los parámetros son más, use métodos.

Las propiedades solo deberían ser simples y obtener uno. Algo más y realmente debería moverse a un método. El código complejo siempre debe estar en los métodos.

Solo uso propiedades para el acceso variable, es decir, obteniendo y configurando variables individuales, o obteniendo y configurando datos en controles. Tan pronto como se necesite / realice cualquier tipo de manipulación de datos, uso métodos.

También una gran ventaja para Properties es que el valor de la propiedad se puede ver en Visual Studio durante la depuración.

Las propiedades son realmente agradables porque están accesibles en el diseñador visual de Visual Studio, siempre que tengan acceso.

Utilizan ser usado si simplemente está configurando y obteniendo y quizás alguna validación que no acceda a una cantidad significativa de código. Tenga cuidado porque la creación de objetos complejos durante la validación no es simple.

Cualquier otro método es la forma preferida.

No se trata solo de semántica. El uso de propiedades inapropiadas comienza a tener rareza en el diseñador visual visual visual.

Por ejemplo, estaba obteniendo un valor de configuración dentro de una propiedad de una clase. La clase de configuración realmente abre un archivo y ejecuta una consulta SQL para obtener el valor de esa configuración. Esto causó problemas en mi aplicación donde el archivo de configuración se abriría y bloquearía por el propio estudio visual en lugar de mi aplicación porque no solo estaba leyendo sino escribiendo el valor de configuración (a través del método setter). Para arreglar esto solo tuve que cambiarlo a un método.

Como una cuestión de diseño, las Propiedades representan los Datos o Atributos del objeto clase, mientras que los métodos son acciones o comportamientos del objeto clase.

En .Net, mundo hay otras implicaciones de usar propiedades:

  • Las propiedades se usan en enlace de datos, mientras que los métodos get_ / set_ no.
  • Propiedades de usuario de serialización XML como mecanismo natural de serilización.
  • El control PropertyGrid y el interno ICustomTypeDescriptor acceden a las propiedades , que se pueden usar de manera efectiva si está escribiendo una biblioteca personalizada.
  • Las propiedades están controladas por atributos , se puede usar sabiamente para diseñar software orientado a aspectos.

Conceptos erróneos (en mi humilde opinión) sobre el uso de las propiedades:

  • Se usa para exponer pequeños cálculos: ControlDesigner.SelectionRules obtiene el bloque se ejecuta en 72 líneas.
  • Utilizado para exponer estructuras de datos internas: incluso si una propiedad no se asigna a un miembro de datos interno, se puede usar como propiedad, si es un atributo de su clase. Viceversa, incluso si es un atributo de las propiedades de su clase no son aconsejables, para devolver los miembros de datos tipo array (en su lugar, los métodos se utilizan para devolver una copia en profundidad de los miembros).

En el ejemplo aquí podría haber sido escrito, con más significado comercial como:

 public String Title { set { Label.Text = text; } } 

Vengo de Java y usé get … set .. method por un tiempo.

Cuando escribo código, no me pregunto: “¿acceder a esta información es simple o requiere un proceso pesado?” porque las cosas pueden cambiar (hoy recuperar esta propiedad es simple, tomonrow puede requerir algún proceso pesado).

Hoy tengo un método SetAge (int age) tomonrow tendré también el método SetAge (date birthdate) que calcula la edad usando la fecha de nacimiento.

Me decepcionó mucho que el comstackdor transforme la propiedad en get y set, pero no considera mis métodos Get … y Set .. como iguales.

Aquí hay un buen conjunto de pautas para cuando usar propiedades vs métodos de Bill Wagner

  • Utilice una propiedad cuando todo esto sea cierto: los captadores deberían ser simples y, por lo tanto, es poco probable que arrojen excepciones. Tenga en cuenta que esto no implica acceso a la red (o la base de datos). Cualquiera puede fallar y, por lo tanto, lanzar una excepción.
  • No deberían tener dependencias el uno del otro. Tenga en cuenta que esto incluiría establecer una propiedad y hacer que afecte a otra. (Por ejemplo, establecer la propiedad FirstName afectaría a una propiedad FullName de solo lectura que comprenda el primer nombre + las propiedades del apellido implican tal dependencia)
  • Deben ser configurables en cualquier orden
  • El captador no tiene un efecto secundario observable. Tenga en cuenta que esta pauta no excluye algunas formas de evaluación perezosa en una propiedad.
  • El método siempre debe regresar inmediatamente. (Tenga en cuenta que esto excluye una propiedad que realiza una llamada de acceso a la base de datos, una llamada al servicio web u otra operación similar).
  • Use un método si el miembro devuelve una matriz.
  • Las llamadas repetidas al captador (sin código intermedio) deberían devolver el mismo valor.
  • Las llamadas repetidas al colocador (con el mismo valor) no deberían producir ninguna diferencia con una sola llamada.

  • El get no debe devolver una referencia a las estructuras internas de datos (Ver ítem 23). Un método podría devolver una copia profunda y podría evitar este problema.

* Tomado de mi respuesta a una pregunta duplicada.