Li Jianzhong (Nanjing University of Posts and Telecommunications (Cornyfield@263.net)
The method, also known as the member function, embodies the behavior of classes or objects. Methods are also divided into static methods and instance methods. The static method can only operate on static domains. The instance method can operate on both instance domains and static domains. Although this method is not recommended, it may be useful in some special cases. The methods are also the same as the domain's five access modifiers-public, protected, internal, protected internal, Private. Their meanings are described above.
Method Parameters
Method parameters are worth special attention. There are four types of parameter transfer: by value, by reference, output, and array ). There is no additional modifier for the value passing parameter. The address passing parameter requires the modifier ref, the output parameter requires the modifier out, And the array parameter requires the modifier Params. If the value of the parameter is changed during a method call, the parameter passed in to the method does not change after the method call is completed, but retains the original value. On the contrary, if the value of the parameter is changed during the method call process, the parameters for passing in the method also change after the call is completed. In fact, we can clearly see the meaning of the two from the name-the pass-through parameter transfers a copy of the call parameter, while the transfer parameter passes the memory address of the call parameter, this parameter points to the same storage location inside and outside the method. Let's take a look at the example below and its output:
using System;class Test{static void Swap(ref int x, ref int y) {int temp = x;x = y;y = temp;}static void Swap(int x,int y) {int temp = x;x = y;y = temp;}static void Main() {int i = 1, j = 2;Swap(ref i, ref j);Console.WriteLine("i = {0}, j = {1}", i, j);Swap(i,j);Console.WriteLine("i = {0}, j = {1}", i, j);}}
After the program is compiled, execute the following output:
I = 2, j = 1
I = 2, j = 1
We can clearly see that the two swap functions swap () get different call results due to the difference in parameters-passing values and passing addresses. Note that the ref modifier must be added to the method call of the address passing parameter at the time of declaration or call.
In general, passing a value does not change the value of a parameter. In some cases, it is wrong. Let's look at the following example:
using System;class Element{public int Number=10;}class Test{static void Change(Element s){s.Number=100;}static void Main() {Element e=new Element();Console.WriteLine(e.Number);Change(e);Console.WriteLine(e.Number);}}
After the program is compiled, execute the following output:
We can see that even if the value passing method still changes the object t of the element class. But strictly speaking, we have changed the domain of object T, not the object t itself. Let's look at the following example:
using System;class Element{public int Number=10;}class Test{static void Change(Element s){Element r=new Element();r.Number=100;s=r;}static void Main() {Element e=new Element();Console.WriteLine(e.Number);Change(e);Console.WriteLine(e.Number);}}
After the program is compiled, execute the following output:
The value passing method does not change the object T whose type is element class! In fact, if we can understand the feature of reference type in Class C #, we can see the difference between the above two examples! During the value transfer process, the reference type itself will not change (T will not change), but the fields contained in the reference type will change (T. Number changed )! C # language reference types include: object type (including built-in class type and user-created class type-inherited from object type), string type, interface type, array type, delegate type. They all have the features shown in the above two examples in the value transfer call.
When values and addresses are passed in, C # requires the user to explicitly initialize the parameters before they are passed in; otherwise, the compiler reports an error! However, if we have a function that does not depend on the initial value of the parameter, what should we do if we only need the function to return its value? This kind of technique is often needed when our function returns a different value. The answer is the output parameter modified with out. However, you must remember that the output parameters are different from the common function return values: the function return values are often stored in the stack and popped up upon return. The output parameters need to be stored in advance, that is, the user needs to declare the variable in advance-of course, the variable can also be initialized. See the following example:
using System;class Test{static void ResoluteName(string fullname,out string firstname,out string lastname) {string[] strArray=fullname.Split(new char[]{' '});firstname=strArray[0];lastname=strArray[1];}public static void Main() {string MyName="Cornfield Lee";string MyFirstName,MyLastName;ResoluteName(MyName,out MyFirstName,out MyLastName);Console.WriteLine("My first name: {0}, My last name: {1}", MyFirstName, MyLastName);}}
After the program is compiled, execute the following output:
My first name: Cornfield, my last name: Lee
All output parameters in the function body must be assigned values; otherwise, the compiler reports an error! The out modifier should also be applied to the function declaration and call. In addition to the special function that acts as the return value, the out modifier ref modifier is similar to the address passing. We can see that C # has completely abandoned the traditional C/C ++ language to give programmers great freedom. After all, C # is used to develop an efficient next-generation network platform, security-including System Security (system structure design) and engineering security (avoiding errors that programmers often make) are important considerations during design, of course, we can see that C # does not lose much language performance due to security. This is exactly what C # is doing, "sharp!
Array parameters are also a frequently used place-passing a large number of array set parameters. Let's take a look at the following example:
using System;class Test{static int Sum(params int[] args){int s=0;foreach(int n in args){s+=n;}return s;}static void Main() {int[] var=new int[]{1,2,3,4,5};Console.WriteLine("The Sum:"+Sum(var));Console.WriteLine("The Sum:"+Sum(10,20,30,40,50));}}
After the program is compiled, execute the following output:
The sum: 15
The total: 150
It can be seen that the array parameter can be an array such as VAR, or can be implicitly converted to an array such as 10, 20, 30, 40, 50. This provides high scalability for our programs.
Different method parameters with the same name may lead to method polymorphism, which is also called the overloading method. It should be noted that the compiler binds methods and method calls at compilation. Methods can only be overloaded by different parameters. Other differences (such as return values) cannot provide effective overloaded information for the compiler.
Method inheritance
The first object-oriented mechanism introduced virtual, override, sealed, and abstract modifiers for the C # method to provide different inheritance requirements. The virtual method of a class can change its implementation method in the class inherited from the class. Of course, this change is limited to the change of the method body, rather than the change of the method header (method declaration. The virtual method changed by the quilt class must be indicated by override in the method header. When a virtual method is called, the instance of this class, that is, the run-time type of the object, determines which method is called. Let's look at the following example:
using System;class Parent{public void F() { Console.WriteLine("Parent.F"); }public virtual void G() { Console.WriteLine("Parent.G"); }}class Child: Parent{new public void F() { Console.WriteLine("Child.F"); }public override void G() { Console.WriteLine("Child.G"); }}class Test{static void Main() {Child b = new Child();Parent a = b;a.F();b.F();a.G();b.G();}}
After the program is compiled, execute the following output:
Parent. f
Child. f
Child. g
Child. g
We can see that the F () method declaration in class child adopts the method of rewriting (new) to block the non-virtual method F () Declaration in class parent. The G () method uses the override method to provide the method's polymorphism mechanism. Note that the rewrite (new) method is different from the override method. In essence, the rewrite method is bound at compile time, and the override method is bound at runtime. It is worth noting that the virtual method cannot be a static method-that is to say, it cannot be modified simultaneously using static and virtual methods, which is determined by its runtime type discrimination mechanism. Override must be used together with virtual, and cannot be used together with static.
What should we do if we do not want to overwrite a virtual method in the inheritance system of a class? The answer is sealed override. We can modify both sealed and override to achieve this goal: sealed override public void F (). Note that sealed and override must be used at the same time. Sealed must also cover a virtual method or a virtual method that is overwritten (instead of sealed. Sealing a non-virtual method is meaningless and incorrect. See the following example:
//sealed.cs// csc /t:library sealed.csusing System;class Parent{public virtual void F() {Console.WriteLine("Parent.F");}public virtual void G() {Console.WriteLine("Parent.G");}}class Child: Parent{sealed override public void F() {Console.WriteLine("Child.F");} override public void G() {Console.WriteLine("Child.G");} }class Grandson: Child{override public void G() {Console.WriteLine("Grandson.G");} }
Abstract methods are logically similar to virtual methods, but cannot be called as virtual methods, rather than declarations rather than implementations of an interface. The abstract method is not similar {...} This method is not allowed. Abstract methods cannot be static. Classes containing abstract methods must be abstract classes and abstract class modifiers must be added. Abstract classes do not have to contain abstract methods. The subclass of an abstract class that inherits an abstract method must overwrite and implement (override is used directly) This method, or combine abstract override to make it continue to be abstracted, or provide no coverage or implementation. The behavior of the latter two is the same. See the following example:
//abstract1.cs// csc /t:library abstract1.csusing System;abstract class Parent{public abstract void F();public abstract void G();}abstract class Child: Parent{public abstract override void F();}abstract class Grandson: Child{public override void F(){Console.WriteLine("Grandson.F");}public override void G(){Console.WriteLine("Grandson.G");}}
Abstract METHODS can abstract an inherited virtual method. Let's look at the following example:
//abstract2.cs// csc /t:library abstract2.csusing System;class Parent{public virtual void Method(){Console.WriteLine("Parent.Method");}}abstract class Child: Parent{public abstract override void Method();}abstract class Grandson: Child{public override void Method(){Console.WriteLine("Grandson.Method");}}
In the final analysis, we grasp the basic mechanism of binding during runtime and compilation, and we can see through various methods such as overload, virtual, override, sealed, and abstract, we can make good use of this tool!
External Method
C # introduces the extern modifier to represent external methods. External methods are implemented in languages other than C #, such as Win32 API functions. As before, external methods cannot be abstract methods. Let's take a look at the following example:
using System;using System.Runtime.InteropServices;class MyClass{[DllImport("user32.dll")]static extern int MessageBoxA(int hWnd, string msg,string caption, int type);public static void Main() {MessageBoxA(0, "Hello, World!", "This is called from a C# app!", 0);}}
After the program is compiled, execute the following output:
Here we call the Win32 API function int messageboxa (INT hwnd, string MSG, string caption, int type ).