virtual keyword in c#

2019-02-09 21:43发布

问题:

I have knowledge of java and have been learning c# for the last couple of days. Now I have come across the "virtual" keyword which, as suggested at this link, is used to allow the corresponding methods, properties etc. to be overriden in the subclasses. Now I think we can override methods even without using the "virtual" keyword. Then why it is necessary?

回答1:

You need the virtual keyword if you really want to override methods in sub classes. Otherwise the base implementation will be hidden by the new implementation, just as if you had declared it with the new keyword.

Hiding the methods by "overriding" them without the base method being declared virtual leaves you without polymorphism, that means: if you "cast" a specialized version to the "base" version and call a method, always the base classes implementation will be used instead of the overridden version - which is not what you'd expect.

Example:

class A
{
    public void Show() { Console.WriteLine("A"); }
}

class B : A
{
    public void Show() { Console.WriteLine("B"); }
}

A a = new A();
B b = new B();

a.Show(); // "A"
b.Show(); // "B"

A a1 = b;
a1.Show(); // "A"!!!


回答2:

virtual is a way of defining that a method has a default implementation, but that that implementation may be overriden in a child class. Other than by using virtual, you cannot override a method directly without using the new keyword (which is generally bad practice).

A good example of the implementation of virtual is the ToString() method. Every object in C# is guaranteed to be able to call ToString() because every object inherits from the base System.Object class, which contains a virtual method ToString(). Derived classes can override this however, and provide their own implementation which may be more useful to the users of the object.

Update: I recently wrote a blog post which goes into this topic in a bit of depth. Check it out here.



回答3:

Now I think we can override methods even without using the "virtual" keyword.

No, you can't. Contrary to Java, in C# members are sealed by default and you cannot override them unless you marked them with the virtual keyword.



回答4:

Take a look at this example:

    void Main()
    {
        var o1 = new S();
        Console.WriteLine(((B)o1).m1());    
    }

    public class B
    {
        public virtual string m1() {
            return "m1";
        }
    }

    public class S : B
    {
        override public string m1() {
            return "overridden m1";
        }
    }

In this example the subclass S is instantiated and assigned to object variable o1. In the Console.WriteLine statement's parameter it is being cast into the base class B, then method m1 is called. Because we have used virtual in the base class B and override in the subclass S, we're getting

overridden m1

as output. If you remove virtual in the method declaration of m1 in B and override in the subclass S then you're getting

m1

as output, which means that the cast also has the effect that the original declaration of method m1 in the base class B is used.

N.B. If you're using the new keyword in subclass S, such as

         new public string m1() {
            return "overridden m1";
        }

assuming that the virtual keyword in the base class B is absent, you're getting the output

m1

as well. If you would not cast it to B, the new method would be used. This is called shadowing (or hiding) a method (the original method of the base class).

Summary:

  • To override a method, which should be effective also if you cast to the base class, use the virtual keyword in the base class and override in the sub class.

  • If you intend to override the method, which should be active in the sub class only, use the new keyword in the sub classes method declaration. As you have seen it works also without it, but it is better if it is there so everyone knows that this is a new version of the method.



标签: c# virtual