C#学习 4 “函数”

执行一行代码的函数可以用C# 6引入的一个功能:表达式体方法(expression-bodied method)。以下函数模式使用=>(Lambda箭头)来实现这一功能。给一个例子。

// C# 6之前的函数
static double Multiple(double a, double b)
{
   return a * b;
}
//
static double Multiple(double a, double b) => a * b;

参数数组
函数可以指定一个(只能一个)特殊参数,这个参数必须是函数定义的最后一个参数,称为参数数组。它允许使用个数不定的参数调用函数,可以用关键字params定义它们。虽然个数不受限制,但是它们的类型必须要和参数数组的类型一致。

class Program
{
   static int SumVals(params int[] vals)
   //这里参数数组是int类型,所以实参也要是int型的,要保持一致
   {
      int sum = 0;
      foreach(int val in vals)
      {
         sum += val;
      }
      return sum;
   }
   static void Main(string[] args)
   {
      int sum = SumVals(1,5,2,4,3);
      //调用时,传入5个int;参数个数随意,不传入参数也可以
   }
}

引用参数ref和值参数
值参数:把一个值传递给形参,函数只改变形参,对实参没有影响。
引用参数:形参和实参相同。也就是函数调用时对形参作出的改变会影响到实参。用ref关键字指定参数,在函数定义和调用中用作参数的修饰符(这个ref和C语言的指针很类似?)。
但ref有两点需要注意——

  1. 由于ref可能会改变实参的值,所以必须在函数调用时使用“非常量变量
  2. 必须使用初始化过的变量。C#中ref参数不能在使用它的函数中初始化。
static void ShowDouble(ref int num)
{
   num *= 2;
   WriteLine($"Num doubled = {num}");
}
// 1的错误实例
const int Num = 5;
ShowDouble(ref Num);
// 1的正确调用
int Num = 5;
ShowDouble(ref Num);

输出参数out
out关键字指定所给的参数是一个输出参数。out也是在函数定义和调用中用作参数的修饰符。函数执行完后,该参数的值将返回给函数调用中使用的变量(和ref基本一样 C语言中的指针)。
out需要注意——

  1. 可以把未赋值的变量用作out参数。
  2. 函数使用out参数时,必须把它看做未赋值。

即调用函数可以把已赋值的变量用作out参数,但存储在该变量中的值会在函数执行时丢失。

// 例 返回数组最大值和它的索引
static int MaxValue(int [] intArray, out maxIndex)
{
   int maxVal = int Array[0];
   for (int i = 1; i < intArray.Length; i++)
   {
      if (intArray[i] > maxVal)
      {
         maxVal = intArray[i];
         maxIndex = i;
      }
   }
   return maxVal;
}
// 调用时必须加上out
int[] exArray = {1, 3, 7, 9};
int maxNumIndex;
WriteLine($"The max value in array is {MaxValue(exArray, out maxNumIndex)}");
WriteLine($"The max value's index (first occured) in array is {maxNumIndex+1}");

全局变量
全局变量一般用static或const定义。如果要修改全局变量的值,只能用static。

// 当全局变量和局部变量名字一样时
class Program
{
   static string myStr;
   static void Write()
   {
      static string myStr;
   }
}
// 那么要这样调用
// 调用全局变量时: Program.myStr;
// 调用局部变量时: myStr;

结构函数
把函数加到结构体中,就能集中处理常见任务,简化操作。

struct CustomerName
{
   public string firstName, lastName;
   public string Name() => firstName + " " +lastName;
}
// 调用
CustomerName a;
a.Name();

函数的重载
函数重载允许创建多个同名函数,函数用的参数类型要不同。每个函数的签名包括函数名和其参数,不同函数的签名不能相同。

static int MaxValue(int[] intArray)
{
   ……
}
static double MaxValue(double[] doubleArray)
{
   ……
}

委托
委托是一种存储函数引用的类型。委托的声明类似于函数,但不带函数体,且要用delegate关键字;委托的声明指定了一个返回类型和一个参数列表
定义了委托后,就可以声明该委托类型的变量。接着把这个变量初始化为与委托具有相同返回类型和参数列表的函数引用。之后就可以用委托变量调用这个函数,就像委托变量是一个函数一样。
有了引用函数的变量后,就可以把委托变量作为参数传递给一个函数。这样该函数就可以使用委托调用它引用的任何函数,而且在运行前不必知道调用的是哪个函数。

// 用委托访问两个函数之一
class Program
    {
        //定义委托,委托(类型?)名是ProcessDelegate
        //可以给委托类型和参数指定任意名称
        delegate double ProcessDelegate(double param1, double param2);
        
        static double Multiply(double param1, double param2) => param1 * param2;
        static double Divide(double param1, double param2) => param1 / param2;

        static void Main(string[] args)
        {
            //用新的委托类型声明一个变量
            ProcessDelegate process;
            
            WriteLine("Enter 2 numbers separated with a comma:");
            string input = ReadLine();
            int commaPos = input.IndexOf(',');
            double param1 = ToDouble(input.Substring(0, commaPos));
            double param2 = ToDouble(input.Substring(commaPos + 1,
                                             input.Length - commaPos - 1));
            WriteLine("Enter M to multiply or D to divide:");
            input = ReadLine();
            if (input == "M")
                //初始化委托变量 也可以这样:process = Multiply;
                process = new ProcessDelegate(Multiply);
            else
                process = new ProcessDelegate(Divide);
            //使用该委托调用所选的函数,这里把委托变量看成一个函数名
            WriteLine("Result: {0}", process(param1, param2));
            ReadKey();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值