代码之家  ›  专栏  ›  技术社区  ›  Arseni Mourzenko

在引用父对象字段、属性或方法时,“base”和“this”之间有什么区别吗?

  •  6
  • Arseni Mourzenko  · 技术社区  · 14 年前

    请考虑以下代码:

    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 回复  |  直到 14 年前
        1
  •  3
  •   KeithS    14 年前

    唯一的区别是显式调用查看父类,而隐式调用通过简单继承最终位于同一位置。性能差异可以忽略不计。正如HansPassant所说,如果在某个时刻将startengine设置为虚拟的,那么对base.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
  •  6
  •   Hans Passant    14 年前

    没有区别,startEngine()不是虚拟的。您不应该使用base,以防您重构它使之成为虚拟的。性能差异不可测量。

        3
  •  2
  •   Jon Hanna    14 年前

    在这种情况下,完全没有性能差异。

    因为startengine不是虚拟的,所以编译器和稍后的抖动,准确地知道调用它意味着什么,无论是在基类、派生类还是从外部类。

    如果startengine是虚拟的,并且编译器和/或抖动可以推断您是针对CityBus而不是从CityBus派生的对象调用的,那么有什么(非常小的)区别 能够 也可作为优化删除。

    如果StartEngine是虚拟的,并且编译器和/或抖动无法推断您是针对CityBus而不是派生类进行调用,那么基础调用或直接调用之间的区别对于正确性至关重要。

    通常,唯一调用基方法的位置 base. 在该方法的重写中,以便更清楚地使用。如果基础版本和派生版本之间的区别在其他地方很重要,那么应该尝试重构以便 base.SomeVirtualMethod() 调用 base.SomeNonVirtual() 因此即使在 derived.SomeVirtualMethod() 改变行为。