The method is a block of code that contains a series of statements. The program enables the statement to be executed by calling the method and specifying any required method parameters. In C#, each executed instruction is executed in the context of the method. The Main method is the entry point for each C# application and is called by the Common Language Runtime (CLR) when the program is started.
Method signature
Declare a method in a class or structure by specifying access levels (such as public or private), optional modifiers (such as abstract or sealed), return value, name of the method, and any method parameters. These components together form the signature of the method.
Notice
For method overloading purposes, the return type of a method is not part of the method signature. But it is part of the method signature when determining compatibility between the delegate and the method it points to.
Method parameters are in brackets and separated by commas. The empty brackets indicate that the method does not require any parameters. This class consists of three methods:
abstract class Motorcycle { // Anyone can call this. public void StartEngine() {/* Method statements here */ } // Only derived classes can call this. protected void AddGas(int gallons) { /* Method statements here */ } // Derived classes can override the base class implementation. public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; } // Derived classes must implement this. public abstract double GetTopSpeed(); }
Method access
Calling a method on an object is like accessing a field. Add a period, method name, and parentheses after the object name. Parameters are listed in brackets and separated by commas. Therefore, the method of the Motorcycle class can be called in the following example:
class TestMotorcycle : Motorcycle { public override double GetTopSpeed() { return 108.4; } static void Main() { TestMotorcycle moto = new TestMotorcycle(); (); (15); (5, 20); double speed = (); ("My top speed is {0}", speed); } }
Method parameters and parameters
This method defines the name and type that specifies any required parameters. When the code calls the method, it provides each parameter with a specific value called a parameter. The parameters must be compatible with the parameter type, but the parameter name (if any) used in the calling code does not need to be the same as the parameter name defined in the method. For example:
public void Caller() { int numA = 4; // Call with an int variable. int productA = Square(numA); int numB = 32; // Call with another int variable. int productB = Square(numB); // Call with an integer literal. int productC = Square(12); // Call with an expression that evaulates to int. productC = Square(productA * 3); } int Square(int i) { // Store input argument in a local variable. int input = i; return input * input; }
Pass by reference and pass by value
By default, when a value type is passed to a method, it is the copy rather than the object itself. Therefore, changes to the parameters do not affect the original copy in the calling method. You can use the ref keyword to pass value types by reference.
When an object of reference type is passed into a method, a reference to the object is passed. That is, the method receives not the object itself, but parameters indicating the location of the object. If you change the member of an object by using this reference, even if the object is passed by value, this change is reflected in the parameters in the calling method.
Create a reference type by using the class keyword, as shown in the following example.
public class SampleRefType { public int value; }
Now if an object based on this type is passed to a method, a reference to the object is passed. The following example passes an object of type SampleRefType to the ModifyObject method.
public static void TestRefType() { SampleRefType rt = new SampleRefType(); = 44; ModifyObject(rt); (); } static void ModifyObject(SampleRefType obj) { = 33; }
The example executes essentially the same as the previous example, passing parameters to the method by value. But because of the reference type, the results are different. Modify the value field of the formal parameter obj in ModifyObject, and also change the value field of the actual parameter rt in the TestRefType method. The TestRefType method displays 33 as output.
Return value
Methods can return values to the caller. If the return type listed before the method name is not void, the method can return the value by using the return keyword. A statement with the return keyword followed by a value matching the return type returns the value to the method caller. The return keyword also stops executing the method. If the return type is void, a return statement without a value can still be used to stop the execution of the method. There is no return keyword, and execution will be stopped when the method reaches the end of the code block. Methods with non-null return types need to use the return keyword to return the value. For example, both methods use the return keyword to return integers:
class SimpleMath { public int AddTwoNumbers(int number1, int number2) { return number1 + number2; } public int SquareANumber(int number) { return number * number; } }
To use the value returned from a method, the calling method can use the method call itself where the same type of value is sufficient. The return value can also be assigned to a variable. For example, the following two code examples achieve the same goal:
(1)
int result = (1, 2); result = (result); // The result is 9. (result);
result = ((1, 2)); // The result is 9. (result);
In this case, it is optional to store the value using the local variable result. This step can help improve the readability of the code, or this step may be necessary if you need to store the original values of parameters across the entire range of the method.
Asynchronous Method
By using the asynchronous function, you can call asynchronous methods without using explicit callbacks, and you don't need to manually split the code across multiple methods or lambda expressions. Asynchronous features have been introduced in Visual Studio 2012.
If you mark a method with the async modifier, you can use the await operator in that method. When the control reaches the await expression in the asynchronous method, the control returns to the caller and the progress in the method will remain suspended until the task is waiting for the completion of the task. After the task is completed, execution can be resumed in the method.
Notice
The asynchronous method returns to the caller when it encounters the first unfinished awaited object or reaches the end of the asynchronous method, whichever occurs first.
An asynchronous method can have a Task<TResult>, Task, or void return type. The Void return type is mainly used to define event handlers that require the void return type. The asynchronous method that returns void cannot be waited for, and the caller returning void method cannot catch the exception raised by the method.
In the following example, DelayAsync is an asynchronous method with the Task<TResult> return type. DelayAsync has a return statement that returns an integer. Therefore, the method declaration of DelayAsync must have the return type of Task<int>. Because the return type is Task<int>, the calculation of the await expression in DoSomethingAsync results in integers as shown in the following statement:
int result = await delayTask
。
The startButton_Click method is an example of an asynchronous method with a void return type. Because DoSomethingAsync is an asynchronous method, the task calling DoSomethingAsync must wait, as shown in the following statement: await DoSomethingAsync();. The startButton_Click method must be defined using the async modifier because the method has an await expression.
// using ; // using ; // This Click event is marked with the async modifier. private async void startButton_Click(object sender, RoutedEventArgs e) { await DoSomethingAsync(); } private async Task DoSomethingAsync() { Task<int> delayTask = DelayAsync(); int result = await delayTask; // The previous two statements may be combined into // the following statement. //int result = await DelayAsync(); ("Result: " + result); } private async Task<int> DelayAsync() { await (100); return 5; }
Output:
Result: 5
An asynchronous method cannot declare any ref or out parameters, but methods with such parameters can be called.
Expression body definition
It is common to have method definitions that return expression results immediately, or a single statement as a method subject. Here is a syntax shortcut to define such methods using =>:
public Point Move(int dx, int dy) => new Point(x + dx, y + dy); public void Print() => (First + " " + Last); // Works with operators, properties, and indexers too. public static Complex operator +(Complex a, Complex b) => (b); public string Name => First + " " + Last; public Customer this[long id] => (id);
If the method returns a void or an asynchronous method, the body of the method must be a statement expression (same as lambda). For properties and indexers, both must be read-only and do not use the get accessor keyword.
Iterator
The iterator performs custom iterations on the collection, such as a list or an array. The iterator returns elements using the yield return statement, one at a time. When the yield return statement arrives, it remembers its current position in the code. The next time the iterator is called, execution will start again from that location.
Call the iterator from the client code by using the foreach statement.
The return type of the iterator can be IEnumerable, IEnumerable<T>, IEnumerator, or IEnumerator<T>.