71 votos

Debo de marcar todos los métodos virtuales?

En Java se puede marcar como método final para hacer que sea imposible de reemplazar.

En C#, usted tiene que marcar método virtual para hacer posible anular.

Significa que en C# se deben marcar todos los métodos virtuales (excepto unos pocos que no quieren ser reemplazado), ya que lo más probable es que no sé en qué forma su clase puede ser hereditario?

137voto

Eric Lippert Puntos 300275

En C#, usted tiene que marcar método virtual para hacer posible anular. Significa que en C# se deben marcar todos los métodos virtuales (excepto unos pocos que no quieren ser reemplazado), ya que lo más probable es que no sé en qué forma su clase puede ser hereditario?

No. Si el lenguaje de los diseñadores de pensamiento virtual que debería haber sido la opción predeterminada, habría sido el valor predeterminado.

Overridablility es una característica, y como todas las características que tiene costos. Los costos de un overrideable método, son considerables: hay gran diseño, la implementación y los costos de las pruebas, especialmente si hay alguna "sensibilidad" a la clase; a los métodos virtuales son las maneras de introducir probado el código de terceros en un sistema y que tiene un impacto en materia de seguridad.

Si usted no sabe cómo tiene la intención de su clase para ser hereditaria, a continuación, no publique su clase porque no ha terminado de diseñar todavía. Su modelo de extensibilidad es definitivamente algo que usted debe saber antes de tiempo; debe influyen profundamente en su diseño y estrategia de pruebas.

Soy partidario de que todas las clases sean sellados y todos los métodos no-virtual hasta que haya un mundo real al cliente centrado en la razón para unseal o a hacer un método virtual.

Básicamente la pregunta es: "yo soy ignorante de cómo mis clientes tienen la intención de consumir mi clase; debo por lo tanto, hacen arbitrariamente extensible?" No; debe convertirse en experto! No me lo pedirías "yo no sé cómo mis clientes van a usar mi clase, por lo que debo hacer todas mis propiedades de lectura-escritura? Y debo hacer todos mis métodos de lectura-escritura de las propiedades de tipo de delegado, de modo que los usuarios pueden reemplazar cualquier método con su propia aplicación?" No, no hace ninguna de esas cosas hasta que haya evidencia de que un usuario realmente necesita esa capacidad! Dedicar su valioso tiempo en el diseño, prueba e implementación de características que los usuarios realmente quieren y necesitan, y hacerlo desde una posición de conocimiento.

26voto

Patrick Klug Puntos 5320

En mi opinión las actualmente aceptadas respuesta es innecesariamente dogmática.

Es cierto que, al no marcar un método como virtual, los demás no pueden reemplazar su comportamiento, y cuando se marca una clase como sealed otros no pueden heredar de la clase. Esto puede causar dolor sustancial. No sé cuántas veces he maldecido una API para el marcado de las clases sealed o no métodos de marcado virtual simplemente porque no anticipar mi caso de uso.

Teóricamente podría ser el enfoque correcto para permitir únicamente la sustitución de métodos y heredar las clases que están destinados a ser reemplazado y heredada, pero que en la práctica es imposible prever todos los escenarios posibles, y a menos que su proyecto es la seguridad crítico que en realidad no es una buena razón para ser tan cerrado.

  1. Si usted no tiene una muy buena razón, entonces no se nota como en las clases de sealed.
  2. No marque cada método como virtual como esta parece un poco overkill y es inusual en C#, pero la marca de los principales métodos de una clase que contienen el comportamiento como virtual.

Una manera de hacer la llamada es mirar el nombre del método o propiedad. Un GetLength() método en una Lista hace exactamente lo que su nombre indica y no permitir que gran parte de la interpretación. Cambiando su aplicación podría no ser muy transparente, de modo marcado como virtual es probablemente innecesario. Marca el Add método virtual es mucho más útil como alguien puede crear una Lista especial que sólo acepta algunos de los objetos mediante el método Add, etc. Otro ejemplo son los controles personalizados. Usted quiere que tome el principal método de dibujo, virtual para que otros puedan usar la mayor parte de la conducta y acaba de cambiar la apariencia, pero usted probablemente no anulan las propiedades X e y.

En la final, a menudo, usted no tiene que tomar esa decisión de inmediato. En un proyecto interno, donde usted puede cambiar fácilmente el código de todos modos yo no preocuparse de estas cosas. Si un método necesita ser reemplazado siempre se puede hacer es virtual cuando esto sucede. Por el contrario, si el proyecto es una API de la biblioteca o de la que es consumida por otras personas y lento para la actualización es sin duda vale la pena pensar en que las clases y los métodos pueden ser útiles. En este caso creo que es mejor ser abierto en lugar de estrictamente cerrado.

22voto

John Saunders Puntos 118808

¡No! Porque usted no sabe cómo de su clase será heredada, debe sólo marcar un método como virtual si usted sabe que usted quiere que sea reemplazado.

5voto

nunespascal Puntos 12686

No. Sólo los métodos que usted quiere que las clases derivadas para especificar debe ser virtual.

Virtual no está relacionado con el final.

Para evitar la superposición de un método virtual en c# utiliza sealed

public class MyClass
{
    public sealed override void MyFinalMethod() {...}
}

4voto

irreputable Puntos 25577

Podemos evocar razones para/de nuevo campamento, pero que es completamente inútil.

En Java hay millones de inesperadas que no es firme métodos públicos, pero vemos muy pocas historias de terror.

En C# hay millones de sellado métodos públicos, y oímos muy pocas historias de terror.

Así que no es un gran problema - la necesidad de reemplazar un método público es raro, por lo que es discutible de cualquier manera.


Esto me recuerda a otro argumento: si la variable local debería ser la final de forma predeterminada. Es una buena idea, pero no podemos exagerar lo valioso que es. Hay miles de millones de variables locales que podrían ser, pero no lo son, final, pero ha demostrado ser un problema real.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X