6 votes

Y a-t-il une différence entre "base" et "this" lorsqu'on fait référence à un champ, une propriété ou une méthode de l'objet parent ?

Considérons le code suivant :

public class Vehicle
{
    public void StartEngine()
    {
        // Code here.
    }
}

public class CityBus : Vehicle
{
    public void MoveToLocation(Location location)
    {
        ////base.StartEngine();
        this.StartEngine();
        // Do other stuff to drive the bus to the new location.
    }
}

Y a-t-il une différence entre this.StartEngine(); y base.StartEngine(); sauf que dans le second cas, StartEngine ne peut pas être déplacée ou surchargée dans la méthode CityBus classe ? Y a-t-il un impact sur les performances ?

6voto

Hans Passant Points 475940

Aucune différence, StartEngine() n'est pas virtuel. Vous ne devriez pas utiliser base, au cas où vous le remaniez un jour pour le rendre virtuel. La différence de performance n'est pas mesurable.

3voto

KeithS Points 36130

La seule différence est un appel explicite pour regarder votre classe parente contre un appel implicite qui se retrouve au même endroit par simple héritage. La différence de performance est négligeable. Comme Hans Passant l'a dit, un appel à base.StartEngine() provoquera un comportement bizarre si vous rendez StartEngine virtuel à un moment donné.

Vous ne devriez pas avoir besoin de l'un ou l'autre de ces qualificatifs pour vous rendre au bon endroit. this.StartEngine() est presque toujours redondant lorsqu'il est explicitement codé. Vous pouvez avoir du code qui met indirectement un this dans une liste d'objets, mais c'est alors la référence de la liste qui est appelée :

public class Vehicle
{
    public void StartEngine()
    {
        // Code here.
    }

    //For demo only; a method like this should probably be static or external to the class
    public void GentlemenStartYourEngines(List<Vehicle> otherVehicles)
    {
       otherVehicles.Add(this);

       foreach(Vehicle v in Vehicles) v.StartEngine();
    }
}

2voto

Jon Hanna Points 40291

Il n'y a absolument aucune différence de performance dans ce cas.

Comme StartEngine n'est pas virtuel, le compilateur, et plus tard le jitter, savent exactement ce que signifie un appel à celui-ci, que ce soit dans la classe de base, la classe dérivée ou depuis une classe extérieure.

Si StartEngine était virtuel, et si le compilateur et/ou le jitter peuvent déduire que vous appelez par rapport à un CityBus plutôt que quelque chose de dérivé d'un CityBus, alors quelle (très petite) différence il y a pourrait être également supprimée à titre d'optimisation.

Si StartEngine était virtuel, et que le compilateur et/ou le jitter ne peuvent pas déduire si vous appelez par rapport à un CityBus plutôt qu'à une classe dérivée, alors la distinction entre un appel de base ou direct est vitale pour la correction.

En règle générale, le seul endroit où l'on peut appeler une méthode de base avec base. est dans une surcharge de cette méthode, pour rendre l'utilisation plus claire. Si la distinction entre la version de base et la version dérivée est importante ailleurs, alors vous devriez essayer de refactorer de manière à ce que base.SomeVirtualMethod() les appels en base.SomeNonVirtual() qui est donc toujours disponible même lorsque derived.SomeVirtualMethod() modifie le comportement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X