Есть ли разница между «base» и «this» при обращении к полю, свойству или методу родительского объекта? - PullRequest
6 голосов
/ 01 сентября 2010

Рассмотрим следующий код:

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

Есть ли разница между this.StartEngine(); и base.StartEngine();, за исключением того, что во втором случае метод StartEngine нельзя переместить или переопределить в классе CityBus? Есть ли влияние на производительность?

Ответы [ 3 ]

6 голосов
/ 01 сентября 2010

Без разницы, StartEngine () не является виртуальным.Вы не должны использовать базу, если вы когда-либо реорганизовали ее, чтобы сделать ее виртуальной.Дифференциал не поддается измерению.

3 голосов
/ 01 сентября 2010

Единственным отличием является явный вызов для просмотра вашего родительского класса по сравнению с неявным, который заканчивается в том же месте простым наследованием. Разница в производительности незначительна. как сказал Ханс Пассант, вызов base.StartEngine () вызовет странное поведение, если в какой-то момент вы сделаете StartEngine виртуальным.

Вам не нужен ни один из квалификаторов, чтобы получить правильное место. this.StartEngine() почти всегда избыточен при явном кодировании. У вас может быть код, который косвенно помещает ссылку this в список объектов, но тогда эта ссылка в списке вызывается:

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();
    }
}
2 голосов
/ 01 сентября 2010

В этом случае нет абсолютно никакой разницы в производительности.

Поскольку StartEngine не является виртуальным, компилятор, а затем и джиттер точно знают, что подразумевается под обращением к нему, будь то в базовом, производном классе или из внешнего класса.

Если бы StartEngine был виртуальным, и компилятор и / или джиттер могут сделать вывод, что вы вызываете относительно CityBus, а не что-то, полученное из CityBus, то какая (очень маленькая) разница может также будет удален в качестве оптимизации.

Если StartEngine был виртуальным, и компилятор и / или дрожание не могут определить, звоните ли вы в отношении CityBus, а не в производный класс, тогда различие между базовым или прямым вызовом жизненно важно для правильности.

Как правило, единственное место для вызова базового метода с base. - это переопределение этого метода, чтобы сделать использование более понятным. Если различие между базовой и производной версией важно в другом месте, вам следует попытаться провести рефакторинг так, чтобы base.SomeVirtualMethod() вызывал base.SomeNonVirtual(), что, следовательно, всегда доступно, даже когда derived.SomeVirtualMethod() меняет поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...