方法(C# 编程指南)
“方法”是包含一系列语句的代码块。 程序通过“调用”方法并指定所需的任何方法参数来执行语句。 在 C# 中,每个执行指令都是在方法的上下文中执行的。 Main 方法是每个 C# 应用程序的入口点,在启动程序时由公共语言运行时 (CLR) 调用。
提示
本主题讨论命名方法。 有关匿名函数的更多信息,请参见匿名函数(C# 编程指南)。
方法签名
通过指定方法的访问级别(例如 public 或 private)、可选修饰符(例如 abstract 或 sealed)、返回值、名称和任何方法参数,可以在类或结构中声明方法。 这些部分统称为方法的“签名”。
提示
为进行方法重载,方法的返回类型不是方法签名的一部分。 但是,在确定委托和委托所指向方法之间的兼容性时,返回类型是方法签名的一部分。
方法参数括在括号中,并用逗号隔开。 空括号表示方法不需要参数。 下面的类包含三个方法:
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();
}
方法访问
在对象上调用方法类似于访问字段。 在对象名称之后,依次添加句点、方法名称和括号。 参数在括号内列出,并用逗号隔开。 因此,可以按以下示例中的方式调用 Motorcycle 类的方法:
class TestMotorcycle : Motorcycle
{
public override double GetTopSpeed()
{
return 108.4;
}
static void Main()
{
TestMotorcycle moto = new TestMotorcycle();
moto.StartEngine();
moto.AddGas(15);
moto.Drive(5, 20);
double speed = moto.GetTopSpeed();
Console.WriteLine("My top speed is {0}", speed);
}
}
方法参数和实参
方法定义指定所需任何“形参”的名称和类型。 调用代码在调用方法时,将为每个形参提供称为“实参”的具体值。 实参必须与形参类型兼容,但调用代码中使用的实参名称(如果有)不必与方法中定义的形参名称相同。 例如:
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;
}
通过引用传递与通过值传递
默认情况下,将值类型传递给方法时,传递的是副本而不是对象本身。 因此,对参数所做的更改对于调用方法中的原始副本没有影响。 可以使用 ref 关键字通过引用传递值类型。 有关更多信息,请参见 传递值类型参数(C# 编程指南)。 有关内置值类型的列表,请参见值类型表(C# 参考)。
“引用类型”通过引用进行传递。 将引用类型的对象传递给方法时,引用指向原始对象而不是副本。 因此,通过此引用所进行的更改将反映在调用方法中。 引用类型是通过使用 class 关键字创建的,如下面的示例中所示:
public class SampleRefType
{
public int value;
}
现在,如果将基于此类型的对象传递给方法,则会通过引用传递该对象。 例如:
public static void TestRefType()
{
SampleRefType rt = new SampleRefType();
rt.value = 44;
ModifyObject(rt);
Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj)
{
obj.value = 33;
}
此示例的效果本质上与前一示例相同。 但是,由于使用的是引用类型,因此 ModifyObject 所做的更改反映在 TestRefType 方法中创建的对象中。 因此,TestRefType 方法将显示值 33。
有关更多信息,请参见传递引用类型参数(C# 编程指南)和引用类型(C# 参考)。
返回值
方法可以向调用方返回值。 如果返回类型(方法名称前列出的类型)不是 void,则方法可以使用 return 关键字来返回值。 如果语句中 return 关键字的后面是与返回类型匹配的值,则该语句将该值返回给方法调用方。 return 关键字还会停止方法的执行。 如果返回类型为 void,则可使用没有值的 return 语句来停止方法的执行。 如果没有 return 关键字,方法执行到代码块末尾时即会停止。 具有非 void 返回类型的方法才能使用 return 关键字返回值。 例如,下面的两个方法使用 return 关键字来返回整数:
class SimpleMath
{
public int AddTwoNumbers(int number1, int number2)
{
return number1 + number2;
}
public int SquareANumber(int number)
{
return number * number;
}
}
若要使用从方法返回的值,调用方法可以在本来使用同一类型的值就已足够的任何位置使用方法调用本身。 还可以将返回值赋给变量: 例如,下面的两个代码示例可实现相同的目的:
int result = obj.AddTwoNumbers(1, 2);
result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);
result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));
// The result is 9.
Console.WriteLine(result);
可以选择使用局部变量(本例中为 result)来存储值。 这有助于提高代码的可读性,并且如果要为方法的整个范围存储参数的原始值,可能必须这样做。
有关更多信息,请参见 return(C# 参考)。
C# 语言规范
有关更多信息,请参见 C# 语言规范。C# 语言规范是 C# 语法和用法的权威资料。