重写函数c#

重写函数c#,c#,virtual-functions,C#,Virtual Functions,我只是想通过一个控制台应用程序来掌握虚拟功能的概念。我注意到,只要重写基类函数,返回baseclassname。functionname(参数)就会自动插入到我的函数体中。为什么会发生这种情况 class advanc { public virtual int calc (int a , int b) { return (a * b); } } class advn : advanc { pu

我只是想通过一个控制台应用程序来掌握虚拟功能的概念。我注意到,只要重写基类函数,返回baseclassname。functionname(参数)就会自动插入到我的函数体中。为什么会发生这种情况

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);
      }        
}

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

Visual Studio正在尝试猜测您想要什么,因此建议您使用此代码


有时,重写函数会扩展基类函数的功能。在这种情况下,可以在被重写的函数中的某个地方调用
base.function

通过重写虚拟函数,您可以扩展基类的功能,然后为“基类功能”调用基类

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

如果您想要完全替换功能,这不是问题,但是如果您想要扩展功能,那么您还应该调用基类

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


默认情况下,VS至少提供父函数在函数中所做的操作。此外,在许多情况下,您需要运行parent然后执行操作(例如,在UI情况下)。有关详细信息,请参阅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.
基类访问只允许在构造函数(实例)中进行 方法或实例属性访问器


这意味着当它调用base.calc时,它将调用它正在重写的父函数。如果不想调用基函数,可以将其删除,但在大多数情况下,它将保留(这就是visual studio自动生成它的原因)

如果在高级函数中不想调用a*b功能,则可以删除基本函数调用并编写自己的函数调用

例如,如果您在advn类中声明:

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

由于行
return base.calc(a,b),基函数体被自动调用但是,您可以简单地使基本函数体不会被自动调用,并按如下方式调用您的函数:

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

    }

IDE试图生成实际编译的可能最简单的重写方法(因此,如果您将实际实现留待以后,您仍然有一段代码没有做很多工作,但仍然编译并生成一个可能不会破坏其余代码的结果)

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

  • 您的子类的行为会在基础上扩展,但不会完全取代它
  • 您正在使用,但您的calc方法不需要更改(您仍然需要实现它,因为它是您正在装饰的原始接口的一部分,但您只是将调用转发到基类,而不更改行为)

  • 我本来可以早点完成编辑的,但我听到食品车停在外面!你能解释一下什么是get和set吗?我没有找到很好的例子reg。这是初始化变量的一种方法吗{get;set;}是一个自动实现的属性。属性使用get和set封装字段,因此不能直接读取或修改。这是一个很好的编程实践。您可以检查是否要阅读更多“如果要删除‘return base.calc(a,b)’行,基类代码将不会执行”的语句完全是胡说八道。是的,您可以删除该行并写入您想要覆盖基本虚拟函数的任何内容。这与基类代码无关。
        class advn : advanc
        {
            public override int calc(int a, int b)
            {
                 return a * b; //anything else;
            }
    
        }