When writing a base-class virtual method, you need to pay attention to the problem that the virtual methods in the base class call each other, which may cause potential errors when the derived class is overloaded. Of course, this error is not a defect in C # language design, but an inevitable implementation. Of course, if we want to write a common group-based base class, we should pay attention to it.
Maybe when we first started Oop, we didn't care about whether there are methods that are virtual or not. Many times we have rewritten (rewrite) The base class methods. Of course, when you need to determine the override, it is essential for the virtual keyword to limit the base class method. So from time to time, we can modify all the methods of the base class as virtual? In this way, although most of the time there is no problem, it is unlikely that it will overload its own base class, but if it is someone else to inherit the base class, then the problem may come.
When we overload an inaccurate base class, the best habit is to call the method of the same name as the following base, which is more common in control development. However, if there is a virtual method between the base classes that calls another overloaded virtual method, the potential error will come out. See the following example (provided by xingd and modified by me ):
Using System;
Public Class Base
{
Public Virtual Void Foo ()
{
Console. writeline ("Base: foo");
This. Bar ();
}
Public Virtual Void Bar ()
{
Console. writeline ("Base: bar");
}
} ;
Public Class Derived: Base
{
Private Object OBJ;
Public Override Void Foo ()
{
Console. writeline ("Derived: foo");
Base. Foo ();
OBJ= NewObject ();
This. Bar ();
}
Public Override Void Bar ()
{
Console. writeline (obj. tostring ());
Console. writeline ("Derived: bar");
}
} ;
Public Class Test
{
Public Static Void Main ()
{
Derived B= NewDerived ();
B. Foo ();
}
} ;
There is no compilation error. Of course, it is not about C # syntax in. The running result is:
E: \ working \ doing > Test
Derived: foo
Base: foo
Unhandled exception: system. nullreferenceexception: object reference not set to an instance of an object.
At derived. Bar ()
At derived. Foo ()
At test. Main ()
ProblemCodeThat is:
Console. writeline ( " Derived: foo " );
Base . Foo ();
OBJ = New Object ();
This . Bar ();
Because the this. Bar () method in base. Foo () has been overloaded, the actual execution is derived: bar. At this time, my OBJ has not been initialized yet.
Of course, it is easy to fix this bug, that is, to change base: bar to a non-virtual method. Since C # can flexibly set virtual to control whether methods need to be overloaded, such problems are caused by code design defects, in addition, this code is generally not designed for writing by a person, but if the base class and the derived class are written by different people, the chance of such an error may be even greater.