2010-10-07 6 views
21

Tiempo para una pregunta teórica que acabo de encontrar.Anulación parcial de una propiedad de automóvil virtual en una clase infantil

El siguiente código es válido y compila:

public class Parent 
{ 
    public virtual object TestProperty { get; set; } 
} 

public class Child : Parent 
{ 
    private string _testValue = "Hello World!"; 

    public override object TestProperty 
    { 
     get { return _testValue; } 
    } 
} 

public class Consumer 
{ 
    Parent p = new Child(); 

    public Consumer(){ p.TestProperty = 3; } 
} 

Mi pregunta es:

¿Por qué C# me permite invalidar parcialmente la propiedad TestProperty automático en un niño cuando se lleva a un comportamiento parcialmente impredecible ? ¿Hay alguna aplicación práctica?

Se me permite establecer el valor de TestProperty utilizando el setter padre (comprobé que se generara el IL y el setter todavía está configurando el objeto de respaldo en la clase principal) aunque el público no tenga acceso al valor.

+1

¡Pregunta interesante! –

+2

Estoy seguro de que hay muchas cosas raras como esta que compilarán y funcionarán, pero que no tienen aplicación práctica y posibles efectos secundarios desagradables. Los martillos construyen casas o aplastan pulgares dependiendo de cómo los uses :) –

+2

@Dave - Muy cierto. Solo quiero asegurarme de que, en este caso, romper los pulgares con un martillo no sirve para algo que simplemente no veo. –

Respuesta

12

Este comportamiento es coherente con las propiedades no implementadas automáticamente en C#. Siempre ha sido posible anular solo un método get o set para una propiedad virtual. Por lo tanto, hacer que sea imposible hacerlo con una propiedad implementada automáticamente crearía una incoherencia innecesaria.

Por ejemplo, la siguiente es legal

class A 
{ 
    public virtual int P1 
    { 
     get { return 42; } 
     set { } 
    } 
} 

class B : A 
{ 
    public override int P1 
    { 
     get { return 18; } 
    } 
} 
+0

Bastante justo. La pregunta, entonces, no está limitada a auto-propiedades. Todavía un poco confuso en la aplicación práctica. Si declaro que toda mi propiedad es una sola unidad y esa unidad está compuesta por un objeto y un objeto ... ¿por qué querría anular uno y dejar al otro con un comportamiento potencialmente confuso? –

+0

@Justin, las porciones get y set de una propiedad son métodos fundamentalmente diferentes, por lo que tiene sentido que puedan ser reemplazados de manera independiente. En términos de por qué querría quizás, quiero agregar validación adicional en el comportamiento del setter o caching en el getter pero mantener el comportamiento predeterminado para el otro. Estoy seguro de que hay varios casos de uso válidos para hacer esto – JaredPar

+1

@JaredPar - Entiendo que son métodos fundamentalmente diferentes, pero lógicamente los dos están acoplados en mi mente. Sin embargo, en términos de diseño del lenguaje, ¿por qué no es necesario reemplazar ambos y luego, si desea mantener la funcionalidad existente, simplemente llama a return base.TestProperty() ;? (tal vez esta es la razón por la que no estoy hecho para el diseño de idiomas) –

1

¿No tiene sentido para un organismo, sin embargo? Si anula parcialmente solo al colocador, eso podría ser útil para que pueda responder a ese evento, además de llamar al base.TestProperty = value, sin tener que preocuparse por una anulación repetitiva del captador.

Cuestiones relacionadas