web-dev-qa-db-fra.com

Convertir une classe dérivée en classe de base

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"

32
Levitikon

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.

35
Jon Skeet

Bien que cela semble irrationnel, mais cela fonctionne

 DerivedClass B = new DerivedClass();

BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B));
36
shazia

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.
11
Papa Burgundy

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");
    }
}
4
oberfreak

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;
  • nom 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();
2
Andrej Adamenko