0

我在基类中实现了一个方法,如下所示:

  class A
    {
        protected void f1()
        {

        }
    }
    class A1 : A
    {
        public void f2()
        {
           //Simple Calling
            f1();
           //Calling using base pointer
            base.f1();
        }

    }

简单调用和使用基指针调用有什么区别?两种方式的优点是什么?

4

7 回答 7

3

在您的示例中没有区别。但是,考虑何时f1是虚拟的并且它在A1类中有另一个实现:

class A
{
    protected virtual void f1()
    {
        Console.WriteLine("A");
    }
}

class A1 : A
{
    public void f2()
    {
       //Simple Calling - prints `A1`
        f1();
       //Calling using base pointer - prints `A`
        base.f1();
    }

    protected override void f1()
    {
        Console.WriteLine("A1");
    }
}

f1()和那时不同base.f1()。当您使用new关键字隐藏派生类中的基本实现时,会出现相同的情况:

protected new void f1()
{
    Console.WriteLine("A1");
}
于 2013-08-22T10:17:45.783 回答
1

在这种情况下,没有。但是想象一下:

class A 
{ 
    public virtual void F() 
    {
    } 
}
class B : A 
{ 
   public override void F() 
   { 
       Console.WriteLine("B"); 
   } 
   public void F2() 
   { 
       F(); /*output: B*/ 
       base.F() /*no output*/ 
   } 
}

这就是base开始派上用场的地方。

于 2013-08-22T10:16:33.810 回答
1

当您覆盖虚拟方法时, this.f1()(或简单地f1())和之间的区别变得相关:base.f1()

class A
{
    public virtual void F()
    {
        Console.WriteLine("A");
    }
}

class B : A
{
    public override void F()
    {
        Console.WriteLine("B");
    }

    void Test()
    {
        F(); // Prints "B"
        this.F(); // Prints "B"
        base.F(); // Prints "A"
    }
}
于 2013-08-22T10:16:45.537 回答
1

仅当您重载/隐藏了基类中定义的方法时,它才有用。

class A1 : A
{
    public void f2()
    {
       //Simple Calling
        f1();
       //Calling using base pointer
        base.f1();
    }

    protected new void f1()
    {
        // I won't be called
    }

}
于 2013-08-22T10:16:50.693 回答
1

当您想要扩展基本方法的功能但又不想复制它时也很有用:

class A
{
    public virtual void F()
    {
        Console.WriteLine("A");
    }
}

    class B : A
    {
        public override void F()
        {
            base.F();
            Console.WriteLine("B");
        }

        void Test()
        {
            F(); // Prints "A B"
        }
    }
于 2013-08-22T10:18:41.210 回答
0

base 关键字用于在链接构造函数时或当您想要访问基类中已被覆盖或隐藏在当前类中的成员(方法、属性、任何内容)时引用基类。例如,

class A {
    protected virtual void Foo() {
        Console.WriteLine("I'm A");
    }
}

class B : A {
    protected override void Foo() {
        Console.WriteLine("I'm B");
    }

    public void Bar() {
        Foo();
        base.Foo();
    }
}

有了这些定义,

new B().Bar();

会输出

I'm B
I'm A

参考

于 2013-08-22T10:17:01.703 回答
0

如果您覆盖 f1,则需要根据需要区分它们。

class A
{
    protected virtual void f1() {   }
}
class A1 : A
{
    protected override void f1() {   }

    public void f2()
    {
       //Simple Calling
        f1();                 <--- this will call to overrided f1 in this class
       //Calling using base pointer
        base.f1();
    }

}
于 2013-08-22T10:17:04.437 回答