在基本类型“virtual”中声明一个方法,然后在子类型中使用“override”关键字重写它,与在子类型中声明匹配的方法时简单地使用“new”关键字相比,两者之间有什么区别?


当前回答

Virtual / override告诉编译器这两个方法是相关的,在某些情况下,当你认为你在调用第一个(虚拟)方法时,实际上应该调用第二个(被重写)方法。这是多态性的基础。

(new SubClass() as BaseClass).VirtualFoo()

将调用子类的重载VirtualFoo()方法。

New告诉编译器,您正在向派生类添加与基类中的方法同名的方法,但它们之间没有关系。

(new SubClass() as BaseClass).NewBar()

将调用BaseClass的NewBar()方法,而:

(new SubClass()).NewBar()

将调用子类的NewBar()方法。

其他回答

Beyond just the technical details, I think using virtual/override communicates a lot of semantic information on the design. When you declare a method virtual, you indicate that you expect that implementing classes may want to provide their own, non-default implementations. Omitting this in a base class, likewise, declares the expectation that the default method ought to suffice for all implementing classes. Similarly, one can use abstract declarations to force implementing classes to provide their own implementation. Again, I think this communicates a lot about how the programmer expects the code to be used. If I were writing both the base and implementing classes and found myself using new I'd seriously rethink the decision not to make the method virtual in the parent and declare my intent specifically.

Virtual / override告诉编译器这两个方法是相关的,在某些情况下,当你认为你在调用第一个(虚拟)方法时,实际上应该调用第二个(被重写)方法。这是多态性的基础。

(new SubClass() as BaseClass).VirtualFoo()

将调用子类的重载VirtualFoo()方法。

New告诉编译器,您正在向派生类添加与基类中的方法同名的方法,但它们之间没有关系。

(new SubClass() as BaseClass).NewBar()

将调用BaseClass的NewBar()方法,而:

(new SubClass()).NewBar()

将调用子类的NewBar()方法。

我总是觉得这样的事情用图片更容易理解:

再一次,用joseph daigle的密码,

public class Foo
{
     public /*virtual*/ bool DoSomething() { return false; }
}

public class Bar : Foo
{
     public /*override or new*/ bool DoSomething() { return true; }
}

如果你像这样调用代码:

Foo a = new Bar();
a.DoSomething();

注意:重要的是,我们的对象实际上是一个Bar,但我们将它存储在类型为Foo的变量中(这类似于强制转换它)。

那么结果将如下所示,这取决于您在声明类时使用的是virtual/override还是new。

下面是一些代码来理解虚拟方法和非虚拟方法行为的区别:

class A
{
    public void foo()
    {
        Console.WriteLine("A::foo()");
    }
    public virtual void bar()
    {
        Console.WriteLine("A::bar()");
    }
}

class B : A
{
    public new void foo()
    {
        Console.WriteLine("B::foo()");
    }
    public override void bar()
    {
        Console.WriteLine("B::bar()");
    }
}

class Program
{
    static int Main(string[] args)
    {
        B b = new B();
        A a = b;
        a.foo(); // Prints A::foo
        b.foo(); // Prints B::foo
        a.bar(); // Prints B::bar
        b.bar(); // Prints B::bar
        return 0;
    }
}

override关键字和new关键字之间的区别在于前者执行方法覆盖,后者执行方法隐藏。

查看以下链接获取更多信息…

MSDN及其他