For exampleCode:
-
- Public VoidShow ()// (1)
-
- {
- Console. writeline ("Nothing");
-
- }
-
-
- Public VoidShow (IntNumber)// (2)
-
- {
-
- Console. writeline (number );
-
- }
-
- /*
- Public int show (INT number) // (3)
-
- {
-
- Console. writeline (number );
-
- Return Number % 5;
-
- }
-
- */
For the above Code, (1) There is no parameter, (2) an int type parameter is used, and an overload is formed between (1) and (2. (2) Compared with (3), only the return value is different. Although the return value is not the same as the reload, methods with the same method name and parameter list and different return values are not allowed in C, therefore, (2) and (3) cannot exist in the code at the same time. (3) there is no way to compile the code without comments.
We have only discussed some basic knowledge about heavy load. Next we will discuss some complicated heavy load situations.
First, let's look at the first version:
-
- UsingSystem;
-
- UsingSystem. Collections. Generic;
-
- UsingSystem. text;
-
-
- NamespaceOverridedemo
-
- {
-
- /// <Summary>
-
- /// Description: This instance is used to describe the relationship between heavy loads.
-
- /// By Zhou Gong
-
- /// Date: 2008-09-04
- /// Starting address: http://blog.csdn.net/zhoufoxcn
-
- /// </Summary>
-
- ClassProgram
-
- {
-
- Static VoidMain (String[] ARGs)
-
- {
-
- String S =Null;
-
- Show (s );
- Object o ="123";
-
- Show (O );
-
- }
-
-
- Static VoidShow (StringS)
-
- {
-
- Console. writeline ("String");
-
- }
-
- Static VoidShow (Object O)
-
- {
-
- Console. writeline ("Object");
-
- }
-
- }
-
- }
Let's guess.ProgramWhat is the running result?
The program running result is as follows:
String
Object
after analyzing the above Code, we found that the show () method has two forms: String-type parameters and Object-type parameters, in a class, there is a phenomenon that the method name is the same, the parameter list is different (the number of parameters or the parameter type is different), we call it overloading, that is, overload. However, the parameters of the show () method are special, because the string class inherits from the object class, that is, the parameters of the show () method have an inheritance relationship. We can draw two conclusions from the results:
(1) from string S = NULL; show (s); the last call is static void show (string S) in this method, we can conclude that method calls in C # Are exactly matched, that is, S is of the string type. Although the string type inherits from the object type, although static void show (Object O) the condition is also met, but in the method declaration, the static void show (string s) Declaration is the closest to the S type (because s is of the string type, the closest to it ), therefore, execute the static void show (string s) instead of the static void show (Object O) method.
(2) from object o = "123"; show (o); finally, the static void show (Object O) method is called, if method overload exists in C #, the method of the object is called based on its refrence type (reference type) instead of the Instance type. Although "123" is of the string type, its refrence type is of the object type. Therefore, the static void show (Object O) method is called instead of the static void show (string s) method ).
the above main () method il code is as follows:
. Method private hidebysig static void main (string [] ARGs) cel managed
{
. Entrypoint
// Code size 24 (0x18)
. Maxstack 1
. Locals Init ([0] string s,
[1] object O)
Il_0000: NOP
Il_0001: ldnull
Il_0002: stloc.0
Il_0003: ldloc.0
Il_0004: Call void overridedemo. Program: Show (string)
Il_0009: NOP
Il_000a: ldstr "123"
Il_000f: stloc.1
Il_0010: ldloc.1
Il_0011: Call void overridedemo. Program: Show (object)
Il_0016: NOP
Il_0017: Ret
} // End of method program: Main
From the above il code, we can see that for string S = NULL, this code is expressed as ldnull in Il.
Based on the above conclusions, let's look at the following code:
-
- UsingSystem;
-
- Public ClassProgram
-
- {Public Static VoidMain ()
-
- {
-
- Show (Null);
-
- Show ("");
-
- Show (1 );
-
- }
-
- Static VoidShow (Object O)
-
- {
-
- Console. writeline ("Object");
-
- }
-
-
- Static VoidShow (string S)
-
- {Console. writeline ("String");
-
- }
-
- }
Guess what the above code execution results will look like?
The program running result is as follows:
String
Object
Object
From the above running results, we can draw the following conclusions:
(1) The last call from show (null) is the static void show (string s) method. We can further say that in C #, the method call should be exactly matched. Although null can be understood as an empty object or an empty string, Here C # is actually a derived class. This is like we have no money. We can say that there is no money or 500, but there is no 50 billion without a penny, so we don't have to say that there is no 50 billion when there is no money. Here, null indicates a null string. Therefore, the show (null) method calls the static void show (string s) method.
This is a bit like the following:
At an event conference, the host said: "If the height is less than MB, please sit in the first to three rows. If the height is less than MB, please do the four to six rows. If the height is less than MB, please sit in the other rows ."
The above statement seems to have some logic problems. We should say that the height is above 1.60m but less than 1.75m. But if you are facing a group of robbers with guns, and when he says the above, you happen to be there and your height is 1.55 m, which row will you sit in? It is impossible for you to take a shot to correct his logical mistake, right? The best way is to sit in rows 1 to 3. Because in any case, your height is definitely less than 1.60m (although your height meets the second condition described by the robbers, that is, the height is less than 1.75 meters, however, you certainly won't take this risk. From the above sentence, we can also infer that people in the middle of the distance from 1.61m to 1.74m sit in four to six rows ).
In the code above, you are a robber with a gun in the runtime environment. Although null can be understood as a null string or a null object, however, it cannot tell you whether this is a null string or a null object, because string is the derived class of the object, therefore, it calls the corresponding method according to the null string type.
(2) The last call of the static void show (string s) method from show ("") further proves that the method call is to select the execution with the most matching parameter as much as possible. Because show ("") is equivalent to: String S = ""; show (s); s reference type is string, so the static void show (string s) method is called.
Here we can assume that a class A is a derived class of the string class (in fact, the string class is sealed, that is, it cannot be inherited, so I am talking about it as a hypothesis ), the above code changes as follows:
-
- UsingSystem;
-
- Public ClassProgram
-
- {Public Static VoidMain ()
-
- {
- Show (Null);
-
- Show ("");
-
- }
-
-
- Static VoidShow (Object O)
-
- {
-
- Console. writeline ("Object");
-
- }
-
-
- Static VoidShow (string S)
-
- {
- Console. writeline ("String");
-
- }
-
-
- Static VoidShow ()// Assume that A is a string derived class. Of course, the string class does not actually have a derived class. Here we only assume that
-
- {
-
- Console. writeline ("");
-
- }
-
-
- }
If the preceding assumption is true, the running result of the above Code should be as follows:
A
String
(3) Why does show (1) Call the static void show (Object O) method? In this class, the most accurate method overload with show (1) should be the static void show (int I) method declaration, but not in the method, because int is inherited from the valuetype class, so if there is no such declaration as static void show (int I), then the next declaration should be static void show (valuetype V). Unfortunately, there is still no such declaration in the method, however, the valuetype class inherits from the object class, so the method overload declaration that is a bit more than static void show (valuetype v) should be static void show (Object O ), this Declaration exists in the class, so the static void show (Object O) method is called. Of course, there is a box in the process from int to object, that is, packing (packing is a conversion from the value type to the reference type). This can be seen from the following il code.
The following is the Il code of the main () method in the second case:
. method private hidebysig static void main (string [] ARGs) cel managed
{< br>. entrypoint
// code size 32 (0x20)
. maxstack 8
il_0000: NOP
il_0001: ldnull
il_0002: Call void overridedemo. program: Show (string)
il_0007: NOP
il_0008: ldstr ""
il_000d: Call void overridedemo. program: Show (string)
il_0012: NOP
il_0013: LDC. i4.1
il_0014: Box [mscorlib] system. int32
il_0019: Call void overridedemo. program: Show (object)
il_001e: NOP
il_001f: Ret
}// end of method program: Main
Next we will make some changes to the Code in the second case. The Code is as follows:
-
- UsingSystem;
-
- UsingSystem. Collections. Generic;
-
- UsingSystem. text;
-
-
- NamespaceOverridedemo
-
- {
-
- /// <Summary>
-
- /// Description: This instance is used to describe the relationship between heavy loads.
-
- /// By Zhou Gong
-
- /// Date: 2008-09-04
- /// Starting address: http://blog.csdn.net/zhoufoxcn
-
- /// </Summary>
-
- ClassProgram
-
- {
-
- Static VoidMain (String[] ARGs)
-
- {
-
- Show (Null);
-
- Show ("");
- Show (1 );
-
- }
-
-
- Static VoidShow (StringS)
-
- {
-
- Console. writeline ("String");
-
- }
-
-
- Static VoidShow (Object O)
- {
-
- Console. writeline ("Object");
-
- }
-
-
- Static VoidShow (Program P)// Program is the class of the current method
-
- {
-
- Console. writeline ("Program");
-
- }
-
- }
- }
What is the running result of the above Code? Can you guess it?
Haha, the above program code has no running result, because it cannot be compiled! The compilation is as follows:
Why can't I compile it?
The reason is the show (null) method! If only the static void show (string S) and static void show (Object O) methods constitute an overload relationship, null can be understood as a Null String reference or a null object reference. Because the restrictions of the string type are more precise, C # matches the string type most accurately, therefore, the static void show (string s) method is executed. This is proved in the previous code. But now we have a static void show (Program p) method overload. null can be understood as a null string type reference or a null program type reference, because the string class and program class are both derived classes of the object class, the reference of the previous inference will not be treated as a null object type. Because there is no inheritance relationship between the string class and the program class, according to the most precise matching principle, the compiler cannot decide whether to match the string class or the program class is the most accurate, so compilation fails.
-