2009-08-18 16 views
33

Duplicar posible:
Properties vs MethodsMétodo vs propiedad en C# - ¿cuál es la diferencia

En el método se puede escribir algo de código y en propiedades también. Por ejemplo, tengo un Nombre de propiedad. Cuando cambie el nombre de la clase, me gustaría obtener algunos datos de la base de datos y cambiar el estado de mi objeto. Puedo agregar este código para establecer parte de mi propiedad. Otra solución es cambiar la parte del conjunto a privado y agregar el método llamado SetName y en este método agregar mi código.

¿Cuál es la diferencia? ¿Cuándo es el momento en que no es bueno poner algún código en getter/setter y cuándo crear un método propio que se use para cambiar mi propiedad y otras partes de mi clase?

Respuesta

50

Aquí es un buen conjunto de directrices de cuándo utilizar las propiedades frente a los métodos de Bill Wagner (enlace fijo)

  • utilizar una propiedad cuando todo esto es verdad: Los captadores deben ser simples y por lo tanto poco probable lanzar 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 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 a una propiedad FullName de solo lectura que comprenda el nombre + las propiedades del apellido implica tal dependencia)
  • Deberían poderse ajustar en cualquier orden
  • El captador no tiene un observable efecto secundario Tenga en cuenta que esta guía no excluye algunas formas de evaluación perezosa en una propiedad.
  • El método siempre debe devolver 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).
  • Utilice 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 de datos internas (Consulte el elemento 23). Un método podría devolver una copia profunda y podría evitar este problema.

+2

+1 para llamarlo guidlines en lugar de reglas, por ejemplo, una carga lenta O El mapeador generalmente viola muchas de estas pautas. –

+0

Absolutamente, todo es relativo, solo aplique cuando sea aplicable. –

+1

El enlace proporcionado por @ChrisBallance devuelve un 404. Un enlace de trabajo a las directrices de Bill Wagner es [aquí] (http://www.srtsolutions.com/properties-vs-methods). +1 para el enlace de todos modos, Chris. –

12

dado una propiedad como esta

private string _name; 
public string Name { get { return _name; } set { _name = value; } } 

es posible escribir los dos métodos siguientes:

public string get_Name() { return _name; } 
public void set_Name(string value) { _name = value; } 

que actúan de forma idéntica. Y, de hecho, esto es exactamente lo que el compilador hace por usted cuando crea una propiedad.

En general, me alejo de las propiedades cuando el código dentro de ellas comienza a parecer "caro", si eso tiene sentido. Quiero que las propiedades se sientan como campos (con efectos secundarios controlados que suceden en momentos específicos), por lo que deberían ser livianas.

8

Una propiedad no es más que azúcar sintáctica. En algunos casos, es mejor definir una propiedad en lugar de un método porque es más clara/más legible.

Las pautas de diseño establecen que, cuando la funcionalidad que está implementando es costosa, se debe preferir un método a una propiedad.

de hecho, una propiedad se implementa como uno o dos métodos; dependiendo de si su propiedad tiene un colocador o no. La propiedad se traduce en un método get_xxx y un set_xxx.

3

Cuando me he encontrado con la necesidad de poner código en un getter/setter pongo el código en un método privado y llamo a ese método desde el getter/setter. De esta forma, el código está disponible en una llamada a método si lo necesito en otro lugar. No estoy seguro si esta es la respuesta que estabas buscando, pero es solo una metodología que uso.

+0

Totalmente de acuerdo. Diseñe para la extensibilidad, no por el momento ... trabajo de hack medio horneado. Y hacer esto es algo simple, no exagerar nada, estás separando cosas, haciéndolas SECAS, e incluso si el código que moviste a un método no se está REUTILIZANDO AHORA ... nunca se sabe cuándo alguien aparte de ti mismo o el proceso o requisito comercial actual puede necesitar usar ese mismo código MÁS TARDE. Eso es diseño de calidad. Los hacks no son buenos. Tener ese código fuera de su propiedad y en un método lo hace más legible y fácil de mantener y más fácil de reutilizar después ... no es necesario refactorizar – PositiveGuy

1

Esencialmente una propiedad es un par de métodos: getProperty y setProperty. Es solo la convención/simplificación de la cosa.

Se supone que el captador de propiedades no tiene efectos secundarios (bueno, pueden tener ciertos efectos secundarios, como la carga diferida).

0

Los métodos hacen algo. Por eso, por lo general, tienen verbos en sus nombres.

Mientras la propiedad devuelve datos.

La línea es simple, una propiedad debe convertirse en un método si se trata de hacer algo más que acceder a los almacenes de datos internos de la clase.

Por ejemplo, si usted es una propiedad llamada NumberOfQuetions para un usuario.Si tiene que ir a la base de datos para obtener el número de preguntas que deberían ser un método. Si está devolviendo una tienda interna, incluso si se realiza alguna lógica en la tienda interna, puede mantener eso en el get.

1

Esto probablemente no es la diferencia más importante, pero una de las diferencias es que el depurador se puede configurar para pasar por encima de propiedades (suponiendo que su código es trivial).

1

prácticamente no hay diferencia (excepto por el "valor" reservado identificador en un montador).

captadores y definidores conseguir internamente traducido en métodos estándar de tal manera que el tiempo de ejecución tiene ni idea de si alguna getter o setter se asocia con una determinada propiedad. El término azúcar sintáctico a menudo se usa para construcciones de conveniencia como estas.

Sin embargo, no es un beneficio importante de ingeniería de software: su código tiende a ser más fácil de entender si se restringe a sí mismo a utilizar captadores y definidores con get y set semántica. Es decir. solo haga los pasos necesarios para proporcionar la propiedad respectiva.

Un caso de uso común para hacer un poco de trabajo extra es por ejemplo el ajuste o conseguir de una propiedad que no está respaldada directamente por un campo miembro. Por ejemplo, tienes una clase que contiene, por ejemplo, un valor que representa una distancia. Su clase podría proporcionar dos Propiedades: Kilómetros y Millas con los respectivos setters y getters. Luego harías conversiones simples en un par y te ahorrarías para almacenar el valor dos veces.

Como regla general, no se debe poner ningún código en un captador que tiene efectos secundarios. Además, el único efecto secundario que debe tener el código en un setter es el cambio de estado en el objeto al que se refiere el setter.

3

Ahora que lo pienso, las propiedades son más que solo azúcar sintáctico. Son la cara pública de sus datos de miembro a su código de miembro.

Por lo tanto, le da una capa limpia para la recuperación o entrada de un solo aspecto de sus datos miembro de su código.

Una DTO, por ejemplo, no es más que un conjunto de propiedades bien escritas, que dividen los datos y el comportamiento de manera eficiente. Sin un DTO, ¿te imaginas unir estrechamente tu DataGrid o Dropdown al complejo método de lógica de negocios?

En pocas palabras, los métodos en realidad están haciendo el trabajo ... Las propiedades incitan a la acción u obtienen el estado.

Sin embargo, puede usar el código de método dentro de sus propiedades ... no es para lo que están diseñadas. Incluso, si tiene que hacerlo, es mejor que realice una llamada limpia a otro método dentro de la propiedad en lugar de escribir su código en él. HTH!

Cuestiones relacionadas