什么是虚拟方法?

69 c# virtual keyword

为什么要将方法声明为"虚拟".

使用虚拟有什么好处?

cgr*_*eno 50

所述虚拟改性剂是用于标记的方法\属性(ECT)可以在派生类通过使用被修改覆盖改性剂.

例:

class A
{
    public virtual void Foo()
       //DoStuff For A
}

class B : A
{
    public override void Foo()
    //DoStuff For B

    //now call the base to do the stuff for A and B 
    //if required
    base.Foo()
}
Run Code Online (Sandbox Code Playgroud)


Lud*_*ton 42

Virtual允许继承类替换基类随后使用的方法.

public class Thingy
{
    public virtual void StepA()
    {
        Console.Out.WriteLine("Zing");
    }

    public void Action()
    {
        StepA();
        Console.Out.WriteLine("A Thingy in Action.");
    }
}

public class Widget : Thingy
{
    public override void StepA()
    {
        Console.Out.WriteLine("Wiggy");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Thingy thingy = new Thingy();
        Widget widget = new Widget();

        thingy.Action();
        widget.Action();

        Console.Out.WriteLine("Press any key to quit.");
        Console.ReadKey();
    }
 }
Run Code Online (Sandbox Code Playgroud)

当您运行程序时,您的输出将是:

Zing 
A Thingy in Action. 
Wiggy 
A Thingy in Action.
Run Code Online (Sandbox Code Playgroud)

请注意,即使Widget调用Thingy级别定义的Action()方法,内部Thingy也称为Widget的StepA()方法.

基本答案是它为类的继承者提供了更大的灵活性.当然,你必须很好地设计你的课程,否则它可能会造成严重破坏.


Jar*_*Par 21

虚方法是一种方法,其中实际的方法调用取决于底层对象的运行时类型.

非虚方法是一种方法,其中调用的实际方法取决于方法调用时对象的引用类型.


Rus*_*Cam 13

MSDN上的虚拟方法

virtual关键字用于修改方法或属性声明,在这种情况下,方法或属性称为虚拟成员.可以通过派生类中的重写成员来更改虚拟成员的实现.

调用虚方法时,将检查对象的运行时类型是否有覆盖成员.如果没有派生类重写成员,则调用派生程度最大的类中的重写成员,该成员可能是原始成员.(有关运行时类型和大多数派生实现的更多信息,请参见10.5.3虚拟方法.)

默认情况下,方法是非虚拟的.您无法覆盖非虚方法.

您不能将virtual修饰符与以下修饰符一起使用:

静态 抽象 覆盖

除了声明和调用语法的差异之外,虚拟属性的行为类似于抽象方法.

  • 在静态属性上使用虚拟修饰符是错误的.
  • 通过包含使用override修饰符的属性声明,可以在派生类中重写虚拟继承的属性.


tva*_*son 6

即使您不打算从类派生,也可能需要将方法标记为虚拟以模拟该类.一些模拟框架只允许您模拟虚拟方法.请注意,实现接口的方法是隐式虚拟的.

我使用具有此限制的RhinoMocks,并且出于这个原因默认将我的方法标记为虚拟.对我来说,这可能是使用虚方法的最大原因,因为继承发挥作用的情况要少得多.


cyc*_*clo 5

虚方法类似于基类中的抽象方法,除了它们在派生类上的实现是可选的.您也可以将逻辑放在虚方法中,并在派生类中重写它们.