C# 当我们不使用';不使用方法隐藏?

C# 当我们不使用';不使用方法隐藏?,c#,method-hiding,C#,Method Hiding,考虑以下代码: internal class Program { private static void Main(string[] args) { var student = new Student(); student.ShowInfo(); //output --> "I am Student" } } public class Person {

考虑以下代码:

internal class Program
   {

      private static void Main(string[] args)
         {
            var student = new Student();
            student.ShowInfo(); //output --> "I am Student"
        }
    }
    public class Person
    {
        public void ShowInfo()
        {
            Console.WriteLine("I am person");
        }
    }

    public class Student : Person
    {
        public void ShowInfo()
        {
            Console.WriteLine("I am Student");
        }
    }
在上面的代码中,我们不使用方法隐藏

当创建学生实例并调用
showinfo
方法时,我的输出是
I am student
我不使用
new
关键字


当我们不使用方法隐藏时,为什么不调用父方法?

它正在使用方法隐藏,它只是隐式使用。应使用
new
关键字显式显示您知道您正在隐藏该方法,但是,您的代码仍将编译并隐藏该方法。虽然这是绝对不推荐的

Student.ShowInfo()
隐藏继承的成员
Person.ShowInfo()

你最好检查一下编译器的警告

“ConsoleApplication5.Program.Student.ShowInfo()”隐藏继承的 成员“ConsoleApplication5.Program.Person.ShowInfo()”。使用新的 关键字,如果要隐藏


使用相同的方法signature
ShowInfo
意味着要隐藏父类方法。
new
关键字不是必需的,它只是让开发人员知道当前方法正在父类中隐藏另一个方法。

无论您是否使用
new
关键字,基本方法都不是虚拟的。因此,将被调用的总是派生方法。唯一的区别是编译器会向您发出警告,因为基本方法是隐藏的,并且您没有显式使用
new
关键字:

“Student.ShowInfo()”隐藏继承的成员“Person.ShowInfo()”。如果要隐藏,请使用新关键字

C#编译器发出此消息是为了警告您,您可能在没有意识到的情况下错误地执行了此操作

为了修复警告,如果有意隐藏,则应使用new关键字:

public new void ShowInfo()
{
    Console.WriteLine("I am Student");
}
如果不是,则应将基本方法设置为虚拟:

public class Person
{
    public virtual void ShowInfo()
    {
        Console.WriteLine("I am person");
    }
}
然后在派生类中重写它:

public class Student : Person
{
    public override void ShowInfo()
    {
        Console.WriteLine("I am Student");
    }
}
显然,在这两种情况下,如果需要,您都可以调用基本方法:

public override void ShowInfo()
{
    base.ShowInfo();
    Console.WriteLine("I am Student");
}

它是隐藏,这就是为什么你会收到一条警告,如果你有意隐藏它,你应该使用
new
关键字。检查
通过继承隐藏的
部分
3.7.1.2

当类或结构 重新声明从基类继承的名称。 这种类型的名称隐藏采用以下形式之一:

•A 类中引入的常量、字段、属性、事件或类型;或 结构隐藏具有相同名称的所有基类成员

•一种方法 在类或结构中引入隐藏所有非方法基类 具有相同名称的成员,以及具有相同名称的所有基类方法 签名(方法名和参数计数、修饰符和类型)

•类或结构中引入的索引器隐藏所有基类 具有相同签名(参数计数和类型)的索引器


原因是,重新声明基类时,基类方法是隐藏的。它被称为。

实际上,从程序逻辑的角度来看,新的修饰符根本没有效果

新修改器的唯一作用是记录您的意图,以便:

  • 编译器可以在适当的时候向您发出警告(例如,在声明中使用新修饰符时不隐藏继承的成员,或者相反,在声明中不使用新修饰符时,即使该声明隐藏了继承的成员)

  • 其他开发人员更容易理解您的代码

隐藏/不隐藏真正重要的是是否使用(仅当继承的成员是虚拟成员时才能使用)。如果不使用覆盖修改器,继承的成员将始终隐藏。在您的示例中,您不使用覆盖修改器,因此您可以隐藏继承的成员


注意:不要像其他人所说的那样混淆,
方法隐藏是隐式的
,无论您是否使用了
new
关键字。您可以使用这段代码进行检查-

     private static void Main(string[] args)
     {
        Person student = new Student();
        student.ShowInfo(); //output --> "I am person"
     }

用派生类实例化基类对象时
,你的
派生方法将不会被调用

,因为据我所知,必须存在
歧义错误
默认情况下,即使你使用
新建
或不使用
var
这里与
学生
相同,因此,您的代码是
Student Student=newstudent()。为什么您希望
student.ShowInfo
使用
Person.ShowInfo
?这是如何工作的?@Kobi它在Java、Python或任何其他语言中是如何工作的,默认情况下方法是虚拟的,或者更确切地说,方法隐藏不是默认的,甚至不是语言特性。事实并非如此,这是一个C++ism/C#ism,反之亦然,但对于OO语言来说,这两种选择都不是显而易见的。@millimoose-除非我遗漏了什么,否则虚拟默认表示
Person x=new Student();x、 ShowInfo()
将使用
Student.ShowInfo
。这很好,我个人更喜欢Java的方法,而不是C。这里有
Student x=newstudent()