Propiedades vs métodos

135

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 en las que es discutible si debemos usar una propiedad o un método. Un ejemplo es este:

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

En el ejemplo, Labeles un control en una página ASPX. ¿Existe algún principio que pueda regir la decisión (en este caso) de hacer de este un método o una propiedad?

Aceptaré la respuesta que es más general y completa, pero que también toca el ejemplo que he dado.

Trumpi
fuente
2
-1 esta pregunta ha sido formulada y respondida antes: stackoverflow.com/questions/164527/…
Element
Los pros y los contras del método / campo / propiedad pueden generar largos debates; uso general de las propiedades: cuando desea campos privados / protegidos pero al mismo tiempo desea exponerlos. Otro uso es tener no solo declaraciones sino también expresiones (acciones si lo desea), incluso if()comprobaciones (según MSDN). Pero esto es complicado ya que el usuario no siempre es consciente del costo de procesamiento detrás del acceso a una variable (propiedad) (es decir, el código no está disponible) y por razones de rigor, uno tendría que comparar la propiedad. Ah, y una "bonificación" no puedes usar punteros con propiedades.
mireazma

Respuestas:

146

Desde la sección Elegir 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 utilizadas como campos, lo que significa que las propiedades no deben ser computacionalmente complejas ni producir efectos secundarios. Cuando no viole 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.

Ken Browning
fuente
3
Si bien estoy de acuerdo con gran parte de eso, no creo que la parte sobre los efectos secundarios sea correcta. Por ejemplo, "Color" a menudo es una propiedad de un objeto, y tiene efectos secundarios obvios (cambiar el color de un objeto). Cambiar las propiedades tiene el obvio efecto secundario de cambiar el estado del objeto.
Erik Funkenbusch 02 de
46
Mystere Man Changing Color es el efecto deseado, no el efecto secundario. El efecto secundario es algo que no se pretende en la acción primaria.
Muhammad Hasan Khan
2
@Mystere Man: cambiar definitivamente el color no es un efecto secundario, estoy completamente de acuerdo con esta respuesta
Ahmed dijo el
2
"Porque los desarrolladores menos experimentados encuentran las propiedades más fáciles de usar". - Como lo veo, esta es la única razón para exponer propiedades. Pero estoy en lo cierto?
Tsabo
2
¿Cuál es la diferencia en la implementación interna de una propiedad frente a un método? ¿Se introduce algo en la pila de llamadas cada vez que se usa una propiedad? Si no, ¿de qué otra manera se maneja?
Praveen
57

Sí, si todo lo que está haciendo 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 estricta y rápida, y diferentes personas a veces no estarán de acuerdo sobre si algo debería ser una propiedad o un método. Lo importante es ser (relativamente) consistente con cómo lo hace (o cómo lo hace su equipo).

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

En términos generales, mi filosofía es que si comienza 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.

cletus
fuente
1
Votado abajo. Esto no es correcto. La complejidad de un getter o setter está encapsulada dentro del código getter / setter. Cuán complejo no es relevante en absoluto, ni lo es si "afecta a varios miembros de datos". Es cierto que los parámetros no estándar o múltiples requerirán un método, pero de lo contrario esta respuesta no es precisa.
Hal50000
La primera oración lo explica todo. Bravo.
SWIIWII
13

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 los captadores y establecedores en Java.

Los métodos encapsulan una operación.

En general, uso 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 candidata a un método.

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

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

Establecer 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;}
}

Establecer el texto:

Title = "Properties vs Methods";
Chuck Conway
fuente
12

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 establece una propiedad definida.

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

Día de robin
fuente
11

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

  • La operación es una conversión, como Object.ToString .
  • La operación es lo suficientemente costosa como para que desee comunicarle al usuario que debería considerar el almacenamiento en caché del resultado.
  • Obtener un valor de propiedad utilizando el descriptor de acceso 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 deben poder establecerse y recuperarse 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.
Gavin Miller
fuente
Estoy de acuerdo en que esto tiene sentido siempre que sea aplicable. ¿Pero estoy en lo cierto, que el uso de propiedades a través de la vinculación XAML en WPF no deja otra opción que hacer las acciones apropiadas en el setter? (especialmente en un nuevo SelectedItem para ComboBoxes, ListBoxes, etc.)
Nicolas
9

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á, de hecho, alterando o recuperando "un atributo esencial o distintivo"? En su ejemplo, está utilizando una función para establecer una propiedad de un cuadro de texto. Eso parece un poco tonto, ¿no?

Las propiedades realmente son funciones. Todos se compilan en getXXX () y setXXX (). Simplemente los oculta en el 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 configurables, 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, 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 matemático al que está adjunto.

Esto puede ser un poco divagante, pero realmente se reduce a decidir cuáles son sus objetos y qué representan. Si no puede determinar si debería ser una propiedad o función, tal vez no importa cuál.

Erik Funkenbusch
fuente
9

Las propiedades sintácticas son atributos de sus objetos. Los métodos son comportamientos de su objeto.

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

En términos de programación orientada a objetos, debe tener una comprensión clara de qué es parte del comportamiento y qué es simplemente un atributo.

Auto {Color, Modelo, Marca}

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

Entonces, si asigna el caso de propiedad / método al objeto de la vida real o lo mira desde un punto de vista simbólico, su confusión realmente desaparecerá.

Muhammad Hasan Khan
fuente
4

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

David Karlaš
fuente
3

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

abatishchev
fuente
3

Las propiedades solo deben establecerse de manera simple y obtener un revestimiento. Algo más y realmente debería trasladarse a un método. El código complejo siempre debe estar en métodos.

Neil Bostrom
fuente
3

Solo uso propiedades para acceso variable, es decir, obtener y configurar variables individuales, u obtener y configurar datos en controles. Tan pronto como se necesita / realiza cualquier tipo de manipulación de datos, uso métodos.

Marcus L
fuente
3

Como cuestión de diseño, las propiedades representan datos o atributos del objeto de clase, mientras que los métodos son acciones o comportamientos del objeto de clase.

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

  • Las propiedades se utilizan en el 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 pasante ICustomTypeDescriptor acceden a las propiedades. , que se puede usar de manera efectiva si está escribiendo una biblioteca personalizada.
  • Las propiedades están controladas por atributos , uno puede usarlo sabiamente para diseñar softwares orientados a aspectos.

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

  • Se usa para exponer pequeños cálculos: ControlDesigner.SelectionRules ¡el bloque get se ejecuta en 72 líneas!
  • Se usa 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 no es aconsejable un atributo de las propiedades de su clase, devolver una matriz como miembros de datos (en su lugar, se utilizan métodos para devolver una copia profunda de los miembros).

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

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

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

Se usan cuando simplemente está configurando y obteniendo y tal vez alguna validación que no accede a una cantidad significativa de código. Tenga cuidado porque crear objetos complejos durante la validación no es simple.

Cualquier otra cosa son los métodos preferidos.

No se trata solo de semántica. El uso de propiedades inapropiadas comienza a tener rarezas en el diseñador visual del estudio 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 abría y bloqueaba con Visual Studio 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 solucionar esto, solo tuve que cambiarlo a un método.

Jeremy Edwards
fuente
1

Aquí hay un buen conjunto de pautas sobre cuándo usar propiedades frente a métodos de Bill Wagner

  • Use una propiedad cuando todo esto sea cierto: los captadores deben ser simples y, por lo tanto, poco probable que arrojen excepciones. Tenga en cuenta que esto implica que no hay acceso a la red (o base de datos). Cualquiera podría fallar y, por lo tanto, arrojaría una excepción.
  • No deberían tener dependencias entre sí. Tenga en cuenta que esto incluiría establecer una propiedad y hacer que afecte a otra. (Por ejemplo, establecer la propiedad FirstName afectaría una propiedad FullName de solo lectura que compuso las propiedades de nombre + apellido implica tal dependencia)
  • Deben ser configurables en cualquier orden
  • El captador no tiene un efecto secundario observable. Tenga en cuenta que esta guía no excluye algunas formas de evaluación diferida en una propiedad.
  • El método siempre debe regresar de inmediato. (Tenga en cuenta que esto excluye una propiedad que realiza una llamada de acceso a la base de datos, una llamada de 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) deben devolver el mismo valor.
  • Las llamadas repetidas al emisor (con el mismo valor) no deberían generar diferencias con respecto a una sola llamada.

  • El get no debe devolver una referencia a las estructuras de datos internas (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.

Chris Ballance
fuente
Las respuestas mejor calificadas y aceptadas aquí stackoverflow.com/a/1294189/1551 ¿Por qué el downvote?
Chris Ballance
2
Me doy cuenta de que llego un poco tarde a la fiesta, pero ese voto negativo probablemente se produjo debido al hecho de que copiaste y pegaste tu respuesta. Al copiar y pegar, admitió que esta pregunta era básicamente un duplicado de la otra. Como tal, debería haberlo marcado como un duplicado en lugar de responderlo. Recomiendo mirar un artículo sobre Meta para saber cómo se deben manejar las preguntas duplicadas.
Joshua
0

Esto es simple.

1: use la propiedad cuando desee que sus datos se validen antes de almacenarlos en el campo. De esta manera, la propiedad proporciona encapsulación para sus campos. Porque si abandona sus campos, el usuario final público puede asignar cualquier valor que pueda o no ser válido según los requisitos de su negocio, como la edad debe ser mayor de 18. Por lo tanto, antes de que el valor se almacene en el campo correspondiente, debemos verificar su validez. De esta manera, las propiedades representan datos.

2: Use el método cuando desee realizar alguna acción, como si estuviera proporcionando algunos datos como parámetro y su método esté procesando en función de los valores suministrados y devolviendo el valor procesado como salida. O desea cambiar el valor de algún campo mediante este cálculo. "De esta manera, el método representa la acción".

El marciano
fuente
-1

Vengo de Java y usé el método get ... set .. por un tiempo

Cuando escribo código, no me pregunto: "¿acceder a estos datos es simple o requiere un proceso pesado?" porque las cosas pueden cambiar (hoy recuperar esta propiedad es simple, mañana puede requerir un proceso pesado o pesado).

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

Me decepcionó mucho que el compilador transformara la propiedad en get y set pero no considero mis métodos Get ... y Set .. como lo mismo.

Marco Staffoli
fuente