2010-10-07 6 views
21

Temps pour une question théorique que je viens de parcourir.Substitution partielle d'une propriété Auto virtuelle dans une classe enfant

Le code suivant est valide et compile:

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; } 
} 

Ma question est:

Pourquoi C# me permet de passer outre partiellement la propriété auto TestProperty chez un enfant quand il conduit à un comportement partiellement imprévisible ? Existe-t-il une application pratique?

Je suis autorisé à définir la valeur de TestProperty en utilisant le setter du parent (j'ai vérifié que l'IL est généré et que le setter définit toujours l'objet de sauvegarde dans la classe parente) même si value n'est pas accessible au public.

+1

Question intéressante! –

+2

Je suis sûr qu'il y a beaucoup de choses bizarres comme celle-ci qui vont compiler et fonctionner, mais n'ont aucune application pratique et potentiellement des effets secondaires laids. Les marteaux construisent des maisons ou écrasent des pouces selon la façon dont vous les utilisez :) –

+2

@Dave - Très vrai. Je veux juste m'assurer que, dans ce cas, briser mes pouces avec un marteau ne sert pas un but que je ne vois pas. –

Répondre

12

Ce comportement est cohérent avec les propriétés non implémentées automatiquement en C#. Il a toujours été possible de ne remplacer qu'une méthode get ou set pour une propriété virtuelle. Par conséquent, le rendre impossible avec une propriété implémentée automatiquement créerait une incohérence inutile.

Par exemple, ce qui suit est légal

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

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

Assez juste. La question n'est donc pas limitée aux auto-propriétés. Encore un peu flou sur l'application pratique. Si je déclare ma propriété entière en tant qu'unité unique et que cette unité est constituée d'un get et d'un set ... pourquoi devrais-je passer outre l'un et laisser l'autre avec un comportement potentiellement confus? –

+0

@Justin, Les parties get et set d'une propriété sont des méthodes fondamentalement différentes, il est donc logique qu'elles puissent être remplacées indépendamment. Pour ce qui est de la raison pour laquelle vous voudriez peut-être ajouter une validation supplémentaire dans le setter ou le comportement de mise en cache dans le getter mais garder le comportement par défaut pour l'autre. Je suis sûr qu'il existe un certain nombre de cas d'utilisation valides pour ce faire – JaredPar

+1

@JaredPar - Je comprends que ce sont des méthodes fondamentalement différentes, mais logiquement, les deux sont couplés dans mon esprit. En termes de conception de la langue, cependant, pourquoi ne pas exiger de surcharger les deux et si vous voulez conserver la fonctionnalité existante, vous appelez simplement return base.TestProperty() ;? (peut-être c'est pourquoi je ne suis pas coupé pour la conception de langues) –

1

-t-il pas logique pour un poseur, si? Si vous ne remplacez que partiellement le setter, cela peut être utile pour que vous puissiez répondre à cet événement, en plus d'appeler le base.TestProperty = value, sans avoir à vous préoccuper du remplacement du getter.

Questions connexes