C#学习笔记06之方法

方法

方法又称函数,本质是具有名称的代码块。 方法是对象或类可执行的计算或操作。方法是封装代码进行重复使用的一种机制,可以封装代码,简化代码,提高可读性,增加代码复用性,降低冗余度,抽象行为。方法只能在类或结构体中声明,通常仅负责单一功能。

方法声明通常包括修饰符、返回值类型、方法名、参数列表(可选)、方法体。每个方法声明都为每个输入参数和返回值指定名称、类型和种类(值、引用或输出)。

  • 修饰符用于修饰方法以确定可访问性、是否为抽象/虚/重写方法等。
  • 返回类型用于指定方法返回给调用者的结果的类型,无返回结果时为void。返回结果需要接收或处理。
  • 方法名采取Pasacl命名法,要求见名知意。
  • 参数列表表示在调用方法时需要传递的形式参数(调用者给的为实际参数),多个以,分隔。调用时需按定义顺序依次传递,个数、类型必须匹配。
  • 方法体指定了在调用方法时执行的语句。方法体可包含零或多条语句,必须书写{}。可以使用return在方法体内任何位置终止方法体的执行,有返回值时return后需要跟返回结果。当方法主体是单个表达式时,可使用Lambda表达式简写。
public string ToString() => "This is an object";
// 等价于
public string ToString() { return "This is an object"; }

通过方法名调用方法,并提供所需参数。

public void Print(string content)
{
    Console.WriteLine(content);
}

Print(ToString());

方法体内声明的仅于内部使用的变量为局部变量。局部变量声明指定了类型、变量名以及可能的初始值,仅在最近的{}范围内可用。C#要求局部变量必须初始化才能获取其值。

方法参数

传递给方法的参数有四类:值参数、引用参数、输出参数和参数数组。此外,C#支持命名参数和可选参数。

值参数传递参数存储的内容,值类型传值,引用类型传引用。值参数是局部变量,从为其传递的实参中获取初始值。

public int Max(int a, int b) => a >= b ? a : b;

public int Max(int[] array)
{
    int count = array.Length;
    if (array == null || count == 0) return 0;
    int max = array[0];
    for (int i = 1; i < count; i++)
    {
        max = Max(max, array[i]);
    }

    return max;
}

引用参数以ref声明,会按引用传递参数,使得形参在方法内部被修改时,实参也随之改变。调用时引用参数必须已显式赋值。通常用于在方法内部修改原变量值。

public void ChangeValueRef(ref int value)
{
    value = 0;
}

int a = 10;
ChangeValueRef(ref a); // 值类型a的值在方法ChangeValueRef()中被改变

输出参数以out声明,会按引用传递参数,使得实参在方法内部被赋值。调用时实参不需要调用者提前赋值,但在方法内部返回时必须赋值。通常用于从方法返回多个结果。

public void GetValueOut(out int value)
{
    value = 0;
}

int a;
GetValueOut(out a); // 值类型a的值在方法GetValueOut()中被改变

参数数组(变长参数)以params声明,允许向方法传递数量不定的同类型参数。参数数组只能是方法的最后一个参数,且参数数组的类型必须是一维数组类型。 在调用包含形参数组的方法时,要么传递形参数组类型的一个实参,要么传递形参数组的元素类型的任意数量实参(数组实例会自动创建,并初始化为包含给定的自变量)。通常用于简化调用。

public void WriteLine(string fmt, params object[] args) { }
Console.WriteLine("x={0}, y={1}", 1, 2);

命名参数是在传参时通过形参名指定参数,而无需按形参顺序传参。 通过对形参命名还能标识每个参数的含义,提高代码可读性。只有命名参数是最后一个或者按顺序传参时才能不对全部参数命名。

public void PrintOrderDetails(string seller, int orderNum, string product) { }
// 按顺序传参
PrintOrderDetails("Gift Shop", 31, "Red Mug");
// 通过命名参数可以不按循序传参
PrintOrderDetails(product: "Red Mug", seller: "Gift Shop", orderNum: 31);
// 仅在两种情况下才能不对全部参数命名
PrintOrderDetails("Gift Shop", 31, productName: "Red Mug"); // 仅命名最后一个参数
PrintOrderDetails(sellerName: "Gift Shop", 31, productName: "Red Mug"); // 按顺序传参

可选参数是在参数列表中给参数赋默认值的参数,此时在外部调用时可选择是否传入该参数。支持多参数默认值,可选参数必须写在非可选参数之后。

public void SetValue(int[] array, int value, bool isSetAll = true)
{
    if (array == null || array.Length == 0) return;
    array[0] = value;
    if (isSetAll)
    {
        int count = array.Length;
        for (int i = 1; i < array.Length; i++)
        {
            array[i] = value;
        }
    }
}

int[] array = { 1, 2, 3 };
SetValue(array, 0);

重载

在同一语句块中,方法名称相同,参数列表不同,即重载。 重载与返回值类型无关,只与参数的类型、数量、顺序有关。refoutparams修饰的参数也可以引起重载。调用时,程序会根据传入的参数列表判断使用哪一个方法。

public int Sum(int a, int b) => return a + b;
public int Sum(int a, int b, int c) => return a + b + c;
public float Sum(float a, float b) => return a + b;
public float Sum(int a, float b) => return a + b;
public float Sum(float a, int b) => return a + b;

重载可以为一组功能相似的方法(不同类型参数的同一类型行为)统一命名以减少方法名数量,达到降低调用成本、防止命名空间污染、提高程序的可读性

递归

递归即让函数自己调用自己。

public void Function()
{
    Function();
}

一个正确的递归函数必须有结束调用的条件,并且该条件必须改变以到达终止递归的目的。

// 例:求一个数n的阶乘
public int GetFactorial(int a)
{
    if (a < 0) throw new ArgumentException();
    if (a == 0 || a == 1) return 1;
    return a * GetFactorial(a - 1);
}

递归简化了代码逻辑,但增加了方法调用开销。

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值