2010-02-20 32 views
14

Estaba revisando algunos códigos hoy y encontré un código antiguo escrito por un desarrollador. Es algo parecido a estemétodos abstractos internos. ¿Por qué alguien los tendría?

public abstract class BaseControl 
{ 
    internal abstract void DoSomething(); 
} 

Si usted tiene una clase derivada dentro del mismo conjunto, que funcionaría

public class DerivedControl : BaseControl 
{ 
    internal override void DoSomething() 
    { 
    } 
} 

Pero derivar la clase base en un montaje diferente daría error de compilación tiempo

DerivedControl does not implement inherited abstract member 'BaseControl.DoSomething() 

Eso me hizo pensar. ¿Por qué alguien declararía un método como resumen interno?

Respuesta

12

El programador original quería hacer que un control derivado estuviera disponible para el código del cliente. Pero evite que el cliente herede y juegue con el método virtual. No es una mala idea, generalmente es fácil romper una clase base anulando un método y haciendo algo como olvidar llamar al método de la clase base.

+0

Puede que no sea una mala idea hasta la cuarta vez que te encuentras con esta suposición condescendiente en una biblioteca de terceros. A menudo significa una tonelada de duplicación innecesaria. (DevExpress, te estoy mirando ...) – jnm2

1

Mi reacción inicial fue que no hay un buen motivo, si desea evitar la herencia externa, entonces debe marcar la clase interna. Pero eso significa que la clase está totalmente oculta a otras asambleas.

Supongo que este método evita la herencia externa al tiempo que conserva la visibilidad.

+1

No, si desea evitar la herencia externa, hace que el constructor sea interno. No es necesario que toda la clase sea interna. – RobSiklos

+0

¿Cuál es la diferencia entre hacer que la clase sea interna y hacer que el constructor sea interno? – RSB

+0

@RobSiklos En qué escenarios, uno debe hacer que la clase sea interna – RSB

6

Un caso obvio es cuando el método recibe o devuelve un tipo interno. Por ejemplo, los métodos centrales de las clases WPF Transform procesan algunos tipos internos de interoperabilidad, que WPF no expone como parte de su API pública. Debido a que la firma incluye tipos internos, el método no puede ser público o protegido. Y, sin embargo, es claramente apropiado (¡necesario!) Que las diversas clases de Transform funcionen polimórficamente. Por lo tanto, los métodos básicos en Transform/GeneralTransform tienen que ser internos.

Otro, pero el motivo relacionado es evitar la derivación externa. Después de todo, los arquitectos de WPF podrían haber expuesto una versión "segura" de los tipos internos de interoperabilidad en un método abstracto protegido, de modo que los usuarios pudieran crear sus propias clases Transform. No lo hicieron porque no querían tener que lidiar con las formas en que las personas pueden usar esa capacidad, p. creando transformaciones no afines. Permitir la derivación externa habría hecho el trabajo de otras clases en WPF enormemente más complejo, por lo que los arquitectos decidieron permitir solo las clases derivadas "aprobadas" al hacer un método abstracto interno.

0

Al definir un método como resumen interno, usted quiere asegurarse de que solo la clase en el mismo ensamblado pueda tener su implementación para su método.

ahora si distribuye un archivo DLL, evitará que el cliente herede y conmutará la implementación.

Cuestiones relacionadas