J'essaie de rafraîchir ma mémoire, mais je ne trouve pas de réponses avec Google.
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
Trace.Write("derived class");
}
}
Si je crée une instance de classe dérivée, comment puis-je la convertir en sa classe de base de sorte que lorsque DoSomething () est appelée, elle utilise uniquement la méthode de la classe de base?
Une distribution dynamique appelle toujours la méthode substituée de la classe dérivée:
DerivedClass dc = new DerivedClass();
dc.DoSomething();
(dc as BaseClass).DoSomething();
Sortie: "classe dérivée"
Vous ne pouvez pas - c'est entièrement délibéré, car c'est à cela que sert le polymorphisme. Supposons que vous ayez une classe dérivée qui applique certaines conditions préalables sur les arguments que vous passez à une méthode redéfinie, afin de maintenir l'intégrité ... vous ne voulez pas pouvoir contourner cette validation et corrompre son intégrité interne.
Au sein de la classe elle-même, vous pouvez appeler de manière non virtuelle base.AnyMethod()
(que ce soit la méthode que vous remplacez ou non), mais ça va parce que c'est la classe elle-même qui décide de permettre potentiellement à son intégrité d'être violée - sans doute qu'elle sait ce qu'il fait.
Bien que cela semble irrationnel, mais cela fonctionne
DerivedClass B = new DerivedClass();
BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B));
Vous POUVEZ absolument (appeler la méthode de base), lisez simplement sur le polymorphisme:
https://docs.Microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism
Exemple:
public class BaseClass
{
public void DoWork() { }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public new void DoWork() { }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}
Et comment l'appeler:
DerivedClass B = new DerivedClass();
B.DoWork(); // This calls the new method.
BaseClass A = (BaseClass)B;
A.DoWork(); // This calls the old method.
Essayez d'utiliser le mot clé new
au lieu de override
Pour autant que je sache, cela devrait permettre le comportement souhaité. Je ne suis pas vraiment sûr de cela, alors ne me blâmez pas si je me trompe!
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public new void DoSomething()
{
Trace.Write("derived class");
}
}
Les solutions avec new
au lieu de override
cassent le polymorphisme. Récemment, je suis arrivé au même problème et l'ai implémenté de la manière suivante. Ma solution présente les avantages suivants:
virtual
et override
reste en place;BaseClass
n'est pas utilisé directement dans le cast de type, donc si j'introduis un intermédiaire MiddleClass
dans la hiérarchie entre BaseClass
et DerivedClass
, qui implémente également DoSomething()
; alors l'implémentation de MiddleClass
ne sera pas ignorée.Voici l'implémentation:
public class BaseClass
{
public virtual void DoSomething()
{
Trace.Write("base class");
}
}
public class DerivedClass : BaseClass
{
public override void DoSomething()
{
Trace.Write("derived class");
}
public void BaseDoSomething()
{
base.DoSomething();
}
}
L'utilisation est:
DerivedClass dc = new DerivedClass();
dc.DoSomething();
dc.BaseDoSomething();