2010-01-19 9 views
8

Considere los empleado, encargado, y clases Asistentes:herencia .NET: suprimir una propiedad de la clase base

public class Emp 
{ 
    public string Name { get; set; } 
    public Manager Manager { get; set; } 
    public Assistant Assistant { get; set; } 
} 

public class Manager : Emp 
{ 
} 

public class Assistant : Emp 
{ 
} 

El objetivo es no permitir una pieza de código para acceder a una propiedad como esta:

var foo = new Manager(); 
var elmo = new Emp(); 
elmo.Manager = foo; 
elmo.Manager.Manager = new Manager(); 
//how to disallow access to Manager.Manager ? 

Porque Manager hereda de Emp, tiene una propiedad .Manager y .Assistant.

Pregunta

¿Hay modificadores en la herencia de aplicación .NET para eliminar los .Manager y .Assistant propiedades?

actualización

Gracias por su grandes respuestas, todo el mundo. Esperaba que la simplificación y la invención de Emp/Mgr se mostraran en esta pregunta. Está claro que la herencia, en este ejemplo, debería tomarse para otra característica común (algo así como Person, donde las clases compartirían nombres, fechas de nacimiento, etc.) ¡Se agradece mucho su opinión!

+0

Huele como un problema de diseño para mí. Mientras que los gerentes pueden informar a otro gerente, los asistentes probablemente no tengan un asistente. Quizás la base debería ser Person ... – Walter

Respuesta

9

Hacer esto violaría el Liskov substitution principle, y suele ser un signo de un diseño cuestionable. En general, cualquier subclase debe poder usarse en cualquier contexto en que sea una clase base. Si Manager s no tienen .Manager s, entonces no son Emp s, y no deberían heredar de ellos.

2

No, no lo hay.

Puede hacer la propiedad de clase base virtual, luego anularla para lanzar una excepción en el colocador, pero no hay forma de dar un error en tiempo de compilación. Después de todo, no hay nada que hacer en tiempo de compilación para evitar

(elmo.Manager as Employee).Manager = new Manager(); 

Sin embargo, puede escribir

public class ManagerEmployee : Emp {  
    public new ManagerEmployee Manager { 
     get { return base.Manager; } 
    } 
} 

Tenga en cuenta que esto no impedirá fundición.

5

No, porque se rompería Liskov's Subsitution Principle. Básicamente, puede agregar cosas, pero no puede llevárselas.

Es posible que pueda anular la propiedad para lanzar una excepción en el momento de la ejecución, pero no puede hacerlo en tiempo de compilación.

En general, si desea desestimar este tipo de cosas, debe considerar la composición en lugar de la herencia, ya que no tiene una relación de herencia genuina.

0

Como han dicho otros. No. Agregaré que si no todos los empleados tienen un gerente y un asistente, entonces la jerarquía de herencia está mal. Parece que lo único que comparten un empleado y un gerente es un nombre. Puede agregarlo a través de la herencia, pero no puede quitarlo a través de la herencia.

0

No, no puede hacer esto, y no le gustaría, ya sea Manager es un empleado y tiene un administrador y un asistente, o no, y por lo tanto debe tener una clase base diferente, es decir, esta situación indica un defecto de diseño.Una posibilidad podría ser devolver nulo para estas propiedades, aunque eso tenga sentido para el dominio.

1

Como la mayoría de las cosas, depende. Dadas las siguientes clases:

public class foo 
{ 
    public string Test { get { return "foo"; } } 
} 

public class bar : foo 
{ 
    public new string Test { get { return "bar"; } } 
} 

y el código siguiente:

 bar a = new bar(); 
     // returns bar 
     literalTest1.Text = a.Test; 

     foo b = new foo(); 
     // returns "foo" 
     literalTest2.Text = b.Test; 

     foo c = new bar(); 
     // returns "foo" 
     literalTest3.Text = c.Test; 

se puede ver, en base a los comentarios anteriores, que puede sustituir una propiedad que no se declara como virtual. Sin embargo, la propiedad reemplazada solo se usará cuando la variable de objeto se declare como el tipo que anula la propiedad, no como ninguno de sus antepasados. Esto efectivamente rompe el polimorfismo.

En su lugar, arregle su clase ancestro.

Cuestiones relacionadas