7.5 C# 方法(声明、参数、静态和动态方法、方法重载)


7.5.1 C# 方法的声明

在C#中,方法(Method)是执行特定任务的代码块。方法可以返回值,也可以不返回值。以下是方法声明的基本语法和组成部分:

方法声明的语法:

[access-modifier] [return-type] 方法名([参数列表]) 
{
    // 方法体
}
  • 访问修饰符access-modifier):定义了方法的可访问性,如 publicprivateprotected 等。

  • 返回类型return-type):指定方法返回值的数据类型。如果方法不返回值,则返回类型为 void

  • 方法名:是一个合法的C#标识符,用来标识这个方法。

  • 参数列表[参数列表]):括号内定义了方法调用时需要传递的参数,包括参数的类型和名称。参数之间用逗号分隔。

  • 方法体:包含方法逻辑的代码块,用一对大括号 {} 包围。

方法声明的组成部分:

  1. 返回类型:指定方法执行完毕后返回的值的类型。如果方法没有返回值,返回类型为 void

  2. 方法名:遵循C#命名规则的有效标识符。

  3. 参数列表:定义了调用方法时需要传递的参数。参数列表可以为空。

  4. 方法体:包含方法执行的具体逻辑。

  5. return语句:如果方法有返回值,必须在方法体中包含 return 语句,并返回一个与方法声明的返回类型一致的值。

示例:

以下是一些方法声明的示例:

// 无返回值的方法
public void DisplayMessage()
{
    Console.WriteLine("Hello, World!");
}

// 有返回值的方法
public int AddNumbers(int a, int b)
{
    return a + b; // 返回两个整数的和
}

// 返回自定义类型的方法
public Person GetPerson(string name, int age, bool gender)
{
    return new Person { Name = name, Age = age, Gender = gender };
}
  • 第一个方法 DisplayMessage 没有返回值,因此它的返回类型是 void

  • 第二个方法 AddNumbers 返回两个整数的和,因此它的返回类型是 int

  • 第三个方法 GetPerson 返回一个自定义类型 Person 的新实例。

注意事项:

  • 方法名应该描述方法的作用。

  • 参数列表应该包含必要的参数,以便方法可以执行其功能。

  • 方法体应该包含实现方法声明要执行的任务的代码。

  • 如果方法有返回值,确保 return 语句返回的值与方法的返回类型一致。

  • 如果方法不返回值,可以省略 return 语句。

  • 访问修饰符应该根据方法的使用场景来确定。例如,如果方法应该被类的所有外部代码访问,可以使用 public。如果方法只在类内部使用,可以使用 private

7.5.2 方法的参数

在C#中,方法的参数可以通过不同的方式传递,包括值传递、引用传递、输出参数和参数数组。这些传递机制提供了灵活性,允许你根据需要选择最合适的方法。

1. 值参数(Value Parameters)

值参数是最常用的参数传递方式。在这种方式中,方法接收的是参数值的副本,因此在方法内部对该参数的任何修改都不会影响原始参数。

示例代码:

public void Swap(double x, double y)
{
    double temp = x;
    x = y;
    y = temp;
}

在这个例子中,即使方法内部交换了xy的值,这种改变不会反映到调用方法的变量上。

2. 引用参数(Reference Parameters)

引用参数允许方法直接修改传递给它的参数的实际值。为此,必须在参数声明前使用ref关键字。

示例代码:

public void Swap(ref double x, double y)
{
    double temp = x;
    x = y;
    y = temp;
}

在这个例子中,调用Swap(ref a, b)会真正交换ab的值。

3. 输出参数(Output Parameters)

输出参数是方法用来返回多个值的一种方式。与引用参数类似,但输出参数在传递前不需要被初始化。

示例代码:

public void Average(int x, int y, out double result)
{
    result = (x + y) / 2.0;
}

调用Average(a, b, out ave)会将计算结果存储在ave中。

4. 参数数组(Param Array)

参数数组允许你传递一个数组或者多个单独的参数值给一个方法。这是通过在参数前使用params关键字实现的。

示例代码:

public double Average(params int[] numbers)
{
    double sum = 0;
    foreach (var number in numbers)
    {
        sum += number;
    }
    return sum / numbers.Length;
}

你可以这样调用Average方法:

int x = Average(1, 2, 3, 4, 5);

或者

int[] numbers = { 1, 2, 3, 4, 5 };
int y = Average(numbers);

参数数组的规则

  • 方法中只能有一个参数数组。
  • 参数数组必须是方法参数列表中的最后一个参数。
  • 参数数组只能是一维数组。
  • 参数数组不能是引用参数或输出参数。

7.5.3 静态和非静态方法

在C#中,方法可以根据它们是否与类的具体实例关联来分类为静态(Static)方法或非静态(Instance)方法。

静态方法

静态方法是属于类的,而不是类的某个特定对象的。这意味着你可以直接通过类名来调用静态方法,而不需要创建类的实例。

特性:

  • 使用 static 关键字声明。
  • 可以通过类名直接调用。
  • 可以访问类的静态成员,但无法访问类的非静态成员。
  • 在静态方法内,使用 this 关键字是不允许的。

示例代码:

public class MathUtility
{
    public static int Add(int a, int b)
    {
        return a + b;
    }
}

// 调用
int result = MathUtility.Add(5, 10);

非静态方法

非静态方法是属于类的具体实例的,这意味着你需要创建一个类的实例后,才能调用非静态方法。

特性:

  • 不使用 static 关键字声明(默认为非静态)。
  • 必须通过类的具体实例来调用。
  • 可以访问类的静态和非静态成员。
  • 在非静态方法内,可以使用 this 关键字来引用当前对象。

示例代码:

public class MathUtility
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

// 调用
MathUtility utility = new MathUtility();
int result = utility.Add(5, 10);

静态和非静态方法的区别

  1. 调用方式:静态方法可以通过类名直接调用,非静态方法必须通过类的实例调用。

  2. 实例成员访问:非静态方法可以访问实例成员(包括其他非静态方法),而静态方法无法直接访问实例成员。

  3. 性能:静态方法通常比非静态方法有略微的性能优势,因为它们不需要通过对象实例来调用。

  4. 使用场景:当方法不需要访问对象的状态时,通常使用静态方法。如果方法需要访问对象的状态或者需要在多个方法调用之间保持状态,应使用非静态方法。

  5. 继承:静态方法不会被子类重写,但可以被隐藏。非静态方法可以被子类重写。

  6. 多态:静态方法不支持多态性,因为它们不依赖于对象的实际类型。非静态方法支持多态性。

静态方法的限制

  • 静态方法不能参与到面向对象的继承、多态等机制中。
  • 静态方法中不能使用 base 关键字。
  • 静态方法不能直接访问类的实例变量或实例方法,除非通过 this 关键字的引用。

7.5.4 方法的重载

在C#中,方法重载(Method Overloading)是同一个类中存在多个同名方法的情况,但是每个方法的参数列表必须不同。参数列表不同可以是参数类型不同、参数数量不同,或者两者都不同。方法重载有助于提高代码的可读性,并且可以进行更细致的操作。

方法重载的规则:

  1. 方法名必须相同:重载的方法在同一个类中必须具有相同的名字。

  2. 参数列表必须不同:参数的数量、类型、顺序至少有一个必须不同。

  3. 返回类型不相关:方法的返回类型不作为区分重载方法的因素。

  4. 访问修饰符不相关:方法的访问修饰符(如public、private等)也不影响重载。

示例代码:

public class Calculator
{
    // 加法 - 重载1:两个整数相加
    public int Add(int a, int b)
    {
        return a + b;
    }

    // 加法 - 重载2:三个整数相加
    public int Add(int a, int b, int c)
    {
        return a + b + c;
    }

    // 加法 - 重载3:两个浮点数相加
    public double Add(double a, double b)
    {
        return a + b;
    }
}

在这个例子中,Calculator 类有三个重载的 Add 方法,每个方法的参数列表都不相同。

调用重载方法:

Calculator calc = new Calculator();

// 调用第一个重载
int sum1 = calc.Add(5, 10);

// 调用第二个重载
int sum2 = calc.Add(5, 10, 15);

// 调用第三个重载
double sum3 = calc.Add(5.5, 10.5);

编译器如何区分重载方法:

当调用一个重载的方法时,编译器会查看方法的签名,即方法名和参数列表。编译器根据调用方法时提供的参数类型和数量来决定具体使用哪个重载版本。

注意事项:

  • 泛型方法的重载:如果方法使用了泛型,那么参数类型相同但泛型参数不同的方法也可以被视为重载。

  • 构造函数也可以重载:构造函数可以基于不同的参数列表进行重载。

  • 方法组转换:在确定调用哪个重载方法时,编译器会考虑方法组转换,以找到最佳匹配。

  • 方法的返回类型:虽然方法的返回类型对于方法的执行有影响,但它不影响方法的重载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值