¿Debo poner métodos de extensión de una interfaz en el archivo interface.cs?


8

Imagina esta configuración:

public interface IMass{
    double Mass {get;}
}

public static class IMassExtension {
    public static double ToKg(this IMass massObject) {
        return massObject.Mass / 1000.0;
    }

    public static double CalculateInteractiveGravity(this IMass massObject, IMass otherMassObject)          
    {
         return blah;
    }
}

¿Está bien poner la clase de extensión en el mismo archivo que la interfaz (es decir, IMass.cs) o debería estar en un archivo separado (IMassExtension.cs)?


Una clase base no es posible aquí. Imagina

public class Person : Animal, IMass {}

y

public class House : Building, IMass {}

@Yusubov La clase base no funcionará aquí, pregunta actualizada
Moop

Respuestas:


13

Sí, eso está totalmente bien. Además, le animo a que haga eso, ya que hace que la funcionalidad disponible en la interfaz sea más reconocible, al tiempo que reduce el ruido en "¿qué funcionalidad hay en este csproj?" Ver en estudio visual.

Los únicos argumentos que he escuchado en contra de esto son:

  • "¡pero entonces tienes 2 tipos por archivo!" - las pautas están ahí para ayudarte, no para atarte las manos. Lo haría solo un tipo si pudiera.
  • "pero esa extensión usa XYZ!" - Sí, si no incluirías el método si fuera una clase abstracta, tampoco deberías conectarlo a la interfaz. Eso no es un problema con esta práctica, sino con su diseño.

Las nuevas características del lenguaje mejoran esto aún más
user1496062

2

En resumen: tener los métodos de extensión en un archivo separado sería el enfoque a seguir. También es muy importante nombrar las extensiones apropiadamente, ya que definitivamente será un tiempo seguro durante el mantenimiento.

Definitivamente preferiría el nombre MassExtensionssobre IMassExtensions. La razón es que para la mayoría de los programadores un prefijo I en un tipo implica que es una interfaz. Este es un patrón muy común y parte de las Pautas de diseño de .NET.

Agregar un prefijo I para el caso del método de extensión rompe los supuestos y las pautas establecidas.

También hay prioridad para esto en la Biblioteca de clases base. La mayoría de los métodos de extensión disponibles IEnumerableestán contenidos en el tipo Enumerable.

Las siguientes publicaciones relacionadas pueden ser útiles:


Esta publicación de blog recomienda contra el mismo espacio de nombres: blogs.msdn.com/b/vbteam/archive/2007/03/10/…
Moop

De acuerdo, debería haber en sus propios espacios de nombres
Yusubov

1

Normalmente, no pondría métodos de extensión en el mismo archivo que la interfaz. ¿La misma biblioteca / paquete? Por supuesto.

En este ejemplo, definitivamente no lo haría. ¿Qué pasaría si alguien implementara masa en unidades imperiales (babosas)? El toKg () debe estar en la interfaz (y tal vez también como toSlug (), pero técnicamente sería derivable de toKg ()), y los métodos de extensión serían métodos como toG (), toMcg (), etc., que podría implementarse utilizando los métodos de interfaz.


0

Lo pondría en un archivo separado y le daría un nombre más descriptivo que "IMassExtension.cs". Quizás algo así como "MassConversions.cs", ya que eso es lo que realmente hace la clase.

No olvide que los métodos de extensión todavía se pueden llamar como si fueran métodos estáticos simples (por ejemplo MassConversions.ToKg(massObject)), por lo que la clase debe nombrarse teniendo esto en cuenta. Además, su clase de extensión no es una interfaz, por lo que podría ser engañoso nombrarla con la 'I' principal.


Bueno, este es solo un ejemplo simple, tengo un montón de métodos de extensión que hacen cosas diferentes, y no hay un buen nombre común para ello
Moop

Esa podría ser una señal de que se debe pensar un poco más en la organización de la funcionalidad. Las clases de "fregadero de cocina" son comúnmente fuentes de mucha agonía, y generalmente deben evitarse. El hecho de que la funcionalidad aparezca en forma de métodos de extensión no es motivo para abandonar una buena estructura de clases.
Eric King

Actualicé la pregunta para mostrar una posible razón por la cual es útil para este diseño.
Moop

Veo su actualización y mi comentario aún se aplica. Haga clases separadas (apropiadamente nombradas) para tipos separados de funcionalidad. En mi opinión, colocarlos a todos en la misma clase es conveniente, pero descuidado.
Eric King

¿Estás diciendo eso Animial : Massy Building : Masssi Massfuera una clase base?
Moop
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.