覆盖函数c#

时间:2011-11-29 10:42:53

标签: c# virtual-method

我只是试图使用控制台应用程序来掌握虚拟功能的概念。我注意到一旦覆盖基类函数,返回baseclassname.functionname(parameters)就会自动插入到我的函数体中。为什么会这样?

class advanc
{
    public virtual int  calc (int a , int b)
    {        
         return (a * b);        
    }        
}

class advn : advanc
{
     public override int calc(int a, int b)
     {
          //automatically inserted
          return base.calc(a, b);
      }        
}

7 个答案:

答案 0 :(得分:11)

通过覆盖虚函数,可以扩展基类的功能,然后调用基类来实现“基本功能”。

如果要删除“return base.calc(a,b)”行,则不会执行基类代码。

如果要完全替换功能,这不是问题,但如果要扩展功能,则还应调用基类。

以下代码演示了这一点(只是将其放在控制台应用程序中)

class advanc
{
    public virtual int calc(int a, int b)
    {
        Console.WriteLine("Base function called");
        return (a * b);
    }
}

class advn : advanc
{
    public bool CallBase { get; set; }
    public override int calc(int a, int b)
    {
        Console.WriteLine("Override function called");

        if (CallBase)
        {
            return base.calc(a, b);
        }
        else
        {
            return a / b;
        }
    }
}

private static void Main()
{
    advn a = new advn();

    a.CallBase = true;
    int result = a.calc(10, 2);
    Console.WriteLine(result);

    a.CallBase = false;
    result = a.calc(10, 2);
    Console.WriteLine(result);
    Console.WriteLine("Ready");
    Console.ReadKey();
}

答案 1 :(得分:4)

Visual Studio正试图猜测你想要什么,所以它会建议你这个代码。

有时,重写的函数扩展基类函数的功能。在这种情况下,在被覆盖的内部的某处调用base.function是可行的。

答案 2 :(得分:2)

这意味着当它调用base.calc时,它将调用它覆盖的parent函数。如果你不想调用基本功能,你可以删除它,但在大多数情况下它会保留(这就是visual studio auto生成它的原因)。

如果在高级功能中你不想调用a * b功能,你将删除基本功能调用并编写自己的功能。

E.G。如果你在你的课堂上宣布这个:

public override int calc(int a, int b)
{
   return Math.Pow(a, b);
}

调用此功能时,您将收到以下信息:

advanc myObj = new advanc();
advn advnObj = new advn();

myObj.calc(5, 2); // will return 10
advnObj.calc(5, 2); // will return 25

答案 3 :(得分:2)

IDE正在尝试生成实际编译的最简单可能的重写方法(所以如果你以后留下实际的实现,你仍然有一段代码不会做太多但仍会编译并产生可能的结果不会破坏你的其余代码。)

此外,在某些情况下,即使在实现之后,对基类的方法的调用也是有意义的:

  1. 您的子类的行为在基础上扩展但不完全替换它
  2. 您正在使用decorator pattern,但您的计算方法不需要更改(您仍然需要实现它,因为它是您正在装饰的原始界面的一部分,但您只是转发呼叫到你的基类而不改变行为)

答案 4 :(得分:1)

IDE只是插入对基本实现的调用。这意味着,默认情况下,覆盖的行为将与它覆盖的方法相同。如果这不是理想的行为(可能不是),只需使用您选择的代码重新进行操作即可。

答案 5 :(得分:1)

默认情况下,VS提供至少执行父项在函数中执行的操作。此外,在许多情况下,您需要运行父项,然后执行您的操作(例如,在UI情况下)。对于base,请参阅MSDN:

  

base关键字用于访问基类的成员   在派生类中:

Call a method on the base class that has been overridden by another method.
Specify which base-class constructor should be called when creating instances 
of the derived class.
     

仅在构造函数(实例)中允许基类访问   方法或实例属性访问器。

答案 6 :(得分:1)

由于行return base.calc(a, b);自动调用基函数体但是,你可以简单地使基函数体不会被自动调用,并像这样调用你的欧文:

    class advn : advanc
    {
        public override int calc(int a, int b)
        {
             return a * b; //anything else;
        }

    }