2010-08-30 14 views
5

Tengo una clase con algunas funciones que, en realidad, son solo métodos "auxiliares" que el código del cliente podría hacer con otras propiedades/métodos de acceso público, y no estoy seguro de si debo definirlas como propiedades con un getter , métodos de instancia o métodos estáticos que toman la instancia como parámetro. Además, también obtuve una interfaz extraída de la clase que se usa prácticamente en todas partes excepto en la construcción, para permitir que mi código use cualquier clase implementada en la interfaz.Métodos auxiliares en C#: ¿Estático o no estático?

La pregunta es, ¿cuál es el mejor desde el punto de vista del diseño? Por ejemplo, como medio de conseguir la primera de esta clase:

class Person : IPerson { 
    private string name; 

    public string Name { get { return this.name; } } 

    // Property with getter 
    public string Initial { get { return this.name.Substring(0,1); } } 

    // Instance method 
    public string GetInitial { return this.name.Substring(0,1); } 

    // Static method 
    public static string GetInitial(IPerson person) { 
    return person.Name.Substring(0,1); 
    } 
} 

La propiedad se presta a más corto código de cliente, más fácil de leer, pero requeriría cualquier implementación contra IPerson a escribir su propia aplicación, al igual que la instancia método.

El método estático significaría que las clases de implementación no necesitarían escribir las suyas propias, y mi código puede garantizar cómo se determina la inicial basándose en el nombre, pero significa que no puede estar en la interfaz y el código del cliente un poco más detallado.

¿Simplemente se reduce a si no es una buena idea permitir que las clases implementadas especifiquen cómo se calculan los métodos auxiliares?

EDITAR: Mención aparte, ¿por qué SO no me permite agregar la etiqueta de mejores prácticas?

+0

Parece que todavía no hay ninguna etiqueta de mejores prácticas. Necesita al menos 1500 reputación para crear nuevas etiquetas. – M4N

+0

Eso es raro ... definitivamente lo fue, lo he usado en el pasado. – Flynn1179

+2

La muerte de las metaetiquetas (por ejemplo, mejores prácticas): http://blog.stackoverflow.com/2010/08/the-death-of-meta-tags/ – M4N

Respuesta

10

¿Qué tal un método de extensión?

namespace IPersonExtensions 
{ 
    public static class IPersonExtensionClass 
    { 
     public static string Initial(this IPerson @this) 
     { 
      return @this.name.Substring(0, 1); 
     } 
    } 
} 

utilizar de esta manera:

string initial = person.Initial(); 

De esta manera, se puede compartir la aplicación sin tener que heredar o reescribir el código. El uso del espacio de nombres separado hace posible que los usuarios elijan si desean usar este código o no.

+0

No pensé en eso ... aunque supongo que ese método probablemente debería devolver una cadena :) – Flynn1179

+3

Parece que Flynn está creando esta clase desde cero. Si ese es el caso, no se debe usar un método de extensión ya que tiene acceso al código fuente. Los métodos de extensión se deben usar cuando no se puede modificar o extender la clase base. MSDN General GuideLines http://msdn.microsoft.com/en-us/library/bb383977.aspx "En general, recomendamos que implemente métodos de extensión con moderación y solo cuando sea necesario. Siempre que sea posible, el código del cliente debe extender un el tipo existente debería hacerlo creando un nuevo tipo derivado del tipo existente ". – sgriffinusa

+0

@Flynn: Debí haberlo solucionado mientras escribías tu comentario. :) –

1

Voy y vienen, pero he comenzado a inclinarme hacia no estático.

Caso para estática: Le obliga a declarar que la función no usa variables miembro y la deja sin estado. Si accidentalmente dejas entrar el estado al necesitar variables miembro, el compilador te advertirá y tendrás que tomar una decisión concreta.

Caso para una función miembro: Las funciones estáticas son difíciles de heredar, por lo que es difícil cambiar el comportamiento. También dificulta las pruebas, ya que es más difícil sustituir esa función para probar otra cosa. Digamos que tiene algo que usó Initial y quería devolver algo específico para una prueba ...

Como un lado (y un ejemplo extremo), algunas de mis extensiones usan un contenedor IOC para localizar una clase concreta y llamar a un miembro en él.

Cuestiones relacionadas