2009-03-18 12 views
9

Estaba leyendo en algún lugar sobre cómo manejar el problema de querer extender una clase sellada en la biblioteca .NET Framework.¿Cómo manejar una clase que desea extender que está sellada en la biblioteca .NET?

Esto es a menudo una tarea común y útil, así que me hizo pensar, en este caso, ¿qué soluciones hay? Creo que hubo un "método" demostrado para extender una clase sellada en el artículo que leí, pero no recuerdo ahora (no fueron los métodos de extensión).

¿Hay alguna otra manera? Gracias

+0

muy relacionadas: http://stackoverflow.com/questions/554145/liskov-substition-and-composition – cregox

Respuesta

8

Hay una herencia 'falsa'. Es decir, implementar la clase base y las interfaces de la otra clase implementa:

// Given 
sealed class SealedClass : BaseClass, IDoSomething { } 

// Create 
class MyNewClass : BaseClass, IDoSomething { } 

A continuación, tiene un miembro privada, por lo general llaman _backing, por lo tanto:

class MyNewClass : BaseClass, IDoSomething 
{ 
    SealedClass _backing = new SealedClass(); 
} 

Esto, obviamente, no se trabajar por métodos con firmas como:

void NoRefactoringPlease(SealedClass parameter) { } 

Si la clase que desea extender hereda de ContextBoundObject en algún momento, echar un vistazo a this article. La primera mitad es COM, la segunda .Net. Explica cómo puede usar métodos proxy.

Aparte de eso, no se me ocurre nada.

+0

Debido a esta herencia estilo wrapping, realmente no entiendo el sentido de las clases "selladas", que claramente no * previenen * que, en la práctica, extienda una clase. Los inventores de las clases selladas deben haber sabido esto, entonces, ¿cuál es el punto en ellos realmente? ¿Para "alentar" a la gente a no extender una clase? ¿Para que sea más doloroso extender una clase? ¿Por qué no solo dice en la documentación, "esta clase no debe ser heredada"? – Jez

+0

@Jez Si va a "solo decir en los documentos, esta clase no debe heredarse" Prefiero configurarla como sellada y no confiar en los documentos. Pero ese no es realmente su uso. No es nada trivial, sin embargo, te recomiendo que hagas una investigación. Mientras estoy leyendo y aprendiendo sobre 'sellado', todavía no tengo ni idea de [por qué usarlo] (http://geekswithblogs.net/gmamaladze/archive/2010/02/01/sealed_keyword.aspx), pero demasiados la gente piensa que las clases deben estar selladas por defecto y luego tienen la palabra clave 'unsealed' en su lugar. – cregox

+0

@Cawas Realmente no me gusta la mentalidad de 'sealed', que parece ser no confiar en el desarrollador. ¿Qué pasa si el desarrollador razonablemente quiere extender una clase? Estas palabras clave simplemente lo hacen más de un dolor en el culo. Es un error, no una característica, y no he visto ningún argumento convincente de lo contrario. De nuevo, no me importa "alentar" a alguien a no extender una clase, pero en última instancia, el desarrollador debe ser capaz de forzar el problema y no ser detenido (u obligado a usar el ajuste, rompiendo el OOP correcto) con una palabra clave. – Jez

0

¿Qué tal los métodos de extensión? Puede "agregar" métodos adicionales de esa manera, sin tener que lidiar con la restricción de herencia.

2

¿Quizás use el Decorator pattern?

Aparte de los métodos de extensión, esta es la única técnica sensata que se me ocurre.

2

No, no puede extender una clase sellada de forma legítima.

TypeMock le permite simulacro clases selladas, pero dudo que lo animen a utilizar la misma técnica para el código de producción.

Si se ha sellado un tipo, eso significa que el diseñador de la clase no lo ha diseñado para la herencia. Usarlo para la herencia en ese punto bien puede causar lotes de dolor, ya sea ahora o cuando la implementación se modifique en una fecha posterior.

Prefieren la composición a la herencia, es mucho más robusto, en mi experiencia. Vea el ítem 16 en "Effective Java (2nd edition)" para más sobre esto.

+0

Gracias por la advertencia de los peligros y dirección (recomendación del libro). – dotnetdev

+1

Effective Java es un libro increíble, incluso para desarrolladores de C#. No todo es relevante para C#, pero está muy bien escrito. –

+1

No recomendaría usar TypeMock fuera de su entorno de prueba. –

2

La única manera que conozco de "extender" una clase sellada sin métodos de extensión es envolviéndola. Por ejemplo:

class SuperString 
{ 
    private String _innerString; 

    public SuperString(String innerString) 
    { 
     _innerString = innerString; 
    } 

    public int ToInt() 
    { 
     return int.Parse(_innerString); 
    } 
} 

Debería exponer todos los mismos métodos/propiedades que la clase de cadena.

Algunos marcos le permiten extender objetos existentes. En WPF, vea Dependency Properties. Para Windows Forms, consulte IExtenderProvider.

6

Los métodos de extensión son de una forma, siendo la alternativa el Patrón de adaptador. Por el cual escribes una clase que delega algunas llamadas al sellado que deseas extender, y agrega otras. También significa que puede adaptar la interfaz completamente en algo que su aplicación encuentre más apropiada.

6

este método ya puede haber sido mencionado anteriormente por su nombre formal, pero no sé su nombre formal, así que aquí está. Este ejemplo "extiende" la clase TextBox (ejemplo en VB). Creo que una ventaja de este método es que no necesita codificar ni exponer explícitamente a los miembros integrados. Espero que esto es relevante:

VB Módulo de clase "MyTextBox":

public Base as TextBox, CustomProperty as Integer 

Private Sub Init(newTextBox as TextBox) 
    Set Base = newTextBox 
End Sub 

public Property Get CustomProperty2() As String 
    CustomProperty2 = "Something special" 
End Property 

Para llamar al código, se podría decir:

Dim MyBox as New MyTextBox 
MyBox.Init MyForm.TextBox3 

desde aquí se tiene acceso a todos los incorporados en los miembros , además de sus miembros personalizados.

Debug.Print MyBox.Base.Text 
MyBox.CustomProperty = 44 

Para pulido adicional, puede hacer que la base de la propiedad predeterminada de la clase, y entonces usted puede dejar de lado "base" cuando se llama a las propiedades de la clase base. Se llama a los miembros de base como esto:

Debug.Print MyBox().Text 
MyBox().Text = "Hello World" 

VBA Demo

Cuestiones relacionadas