C# “什么是”呢;公开新的虚拟无效方法();什么意思?

C# “什么是”呢;公开新的虚拟无效方法();什么意思?,c#,C#,什么时候用新的虚拟关键词来装饰的方法?什么是感情?比如定义一个接口,并添加一个类来继承接口。而采用新的虚拟仪器来实现接口方法 interface IPrinter { void Print(); } public class PrinterOne : IPrinter { public void Print() { Console.WriteLine("PrinterOne."); } } public class PrinterTwo

什么时候用新的虚拟关键词来装饰的方法?什么是感情?比如定义一个接口,并添加一个类来继承接口。而采用新的虚拟仪器来实现接口方法

 interface IPrinter
{
    void Print();
}

 public class PrinterOne : IPrinter
{
    public void Print() 
    {
        Console.WriteLine("PrinterOne.");
    }
}

public class PrinterTwo : PrinterOne
{
    public new virtual void Print()
    {
        Console.WriteLine("PrinterTwo.");
    }
}

public class PrinterThree : PrinterTwo
{
    public override void Print()
    {
        Console.WriteLine("PrinterThree.");
    }
}

public class PrinterFour : PrinterThree
{
    public override void Print()
    {
        Console.WriteLine("PrinterFour.");
    }
}

 static void Main(string[] args)
    {
        IPrinter iprinter = new PrinterFour();
        iprinter.Print();//the output is PrinterOne? why???
        Console.ReadLine();
    }

像这样使用的
new
关键字是成员隐藏

请注意,我从未见过它与
virtual
关键字一起使用。它只允许从
PrinterTwo
派生的类型覆盖
Print
方法实现


以这种方式使用的
new
关键字允许类型隐藏基类型的成员,但仅当您使用类型本身的变量时

例如,如果您要执行以下操作:

PrinterOne one = new PrinterTwo();
one.Print();
它不会调用
PrinterTwo
中的方法,因为它不是继承链的一部分

至于你什么时候会这么做。。。当你真的,真的因为我想不出的一些奇怪的原因(可能是反射?)而需要时,你不能在
printrone
中编辑代码

就我个人而言,我永远不会这么做

至于为什么输出是打印机1。。。调用
IPrinter.Print
将针对其定义的类型调用(
PrinterOne
,在本例中),这将使您回到我上面的示例中,关于
new
关键字被忽略,除非您与具有该关键字的类型对话

基本上,使用
IPrinter
与上面的小示例中使用
PrinterOne
类似


要解决此问题,请使
PrinterOne
方法
virtual
,并完全取消
PrinterTwo
new
virtual
是两个(大部分)不相关的关键字

new
意味着它会隐藏基本方法。
virtual
允许子类重写它


通过接口调用方法会导致调用基方法,因为基方法不是虚拟的,派生类不会显式地重新实现接口(这会导致方法重新映射)

这称为方法隐藏。当需要为无法重写的方法提供自己的实现时,可以使用此选项。由于
printrone.Print
不是虚拟方法,因此无法重写它。相反,
new
关键字用于创建相同的方法签名,该签名隐藏了原始方法。将使用新方法代替。将
virtual
关键字添加到此中,可以通过派生类覆盖新方法

只有通过定义容器(例如,
printwoo
)调用隐藏原始方法的新方法时,才会调用该方法。通过接口调用它将调用原始方法。请注意,该方法从未被删除或替换,因此通过直接访问接口,原始实现仍然存在。

new modifier

当用作修饰符时,new关键字显式隐藏从基类继承的成员

这意味着该方法不会重写虚基类方法,但在派生类的实例上调用时,它仍然优先。换句话说,新方法只影响派生类的变量,而不影响基类

虚拟修改器

virtual关键字用于修改方法、属性、索引器或事件声明,并允许在派生类中重写它


这意味着可以在派生类中重写该方法。在基类变量上调用虚方法时,如果基类变量包含已重写虚方法的派生类实例,则会调用派生类实现。这与new关键字的行为相反。

//输出为printrone?为什么?因为只有printrone实现接口