• C#基础 [08] 方法 [下]


    一、参数

     1.参数是什么?

        很多情况下,我们声明一个方法,就是为了它的返回值。这我们只需要在方法头中指定方法的返回类型,并且在方法体中使用return语句即可完成。但是,还有一些情况下,只通过这种方式是实现不了的。比如,需要将一些外部数据数据传入方法参与运算,或者需要多个返回值。这时,我们就需要一种称为“参数”的变量来充当这个传递员的角色。

        参数就是声明在方法头的参数列表中的特殊变量,它的作用就是为方法传入数据或将方法体中得到的结果传出方法。

      2.形参和实参

        1).形参

          形参就是声明在方法头的参数列表中的一种本地变量。它的声明和普通的本地变量一样,需要有类型和变量名;一个方法可以有任意数目的形参声明,多个形参声明之间用逗号分隔;除了output参数而外,参数在使用之前都要初始化为明确的值,否则方法就会报错。下面是一个带有两个形参列表的方法示例:

     1         /// <summary>
     2         /// 输出两数之和
     3         /// </summary>
     4         /// <param name="x">int类型的形参x</param>
     5         /// <param name="y">float类型形参y</param>
     6         public void PrintSum(int x, float y)
     7         {
     8             // 在方法体中,用实参初始化之后的形参的使用和本地变量一样
     9             float z = x + y;
    10             Console.WriteLine("{0} + {1} = {2}", x, y, z);
    11         }

        2).实参

          上面提到,调用一个带参数的方法时,形参的值必须在代码开始执行之前被初始化。这个用于初始化形参的变量或者表达式就称作实参(argument)。实参位于方法调用的参数列表中;每个实参的数据类型必须和声明它的形参的数据类型一致,或者可以隐式转换。下面是调用上一个方法传递实参的示例:

    1             // 调用方法,传递实参。注意:实参必须是一个确定的值或者具有确定值的表达式
    2             p.PrintSum(1, 2f);

      3.值参数

        值参数就是实参通过复制“实际值”到形参的方式把数据传递到方法体。值参数是默认的参数类型。当使用值参数调用方法时,系统做如下操作:第一步,在栈中为形参分配空间;第二步,复制实参的值到形参。下面是一个值参数的示例:

    View Code
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             var p = new Program();
     6             var a1 = new MyClass();
     7             var a2 = 10;
     8             // 方法调用:传实参,值参数的实参不一定是变量,可以是计算成相应类型值的表达式
     9             p.MyMethod(a1, a2 + 5);
    10         }
    11 
    12         // 方法声明:声明形参
    13         void MyMethod(MyClass f1, int f2)
    14         {
    15             f1.val += 5;
    16             f2 += 5;
    17         }
    18     }
    19 
    20     class MyClass
    21     {
    22         public int val = 20;
    23     }

       下图说明这一方法调用过程:

      

     4.引用参数

        引用参数就是一种实参复制引用地址到实参的参数。使用引用参数的方式:第一,在方法的声明和调用中都要使用ref修饰符;第二,实参必须是变量,而且在方法调用之前必须被赋值。引用参数的形参变量和实参变量指向相同的内存位置,在方法执行过程中对实参做的任何修改对形参都是可见的。

        下面的示例改写了MyMethod方法:

    View Code
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             var p = new Program();
     6             var a1 = new MyClass();
     7             var a2 = 10;
     8             // 方法调用:传实参,引用参数的实参必须是一个已赋值的变量
     9             // p.MyMethod(ref a1, ref a2 + 5); 错误,实参必须是一个已赋值的变量。
    10             p.MyMethod(ref a1, ref a2);
    11         }
    12 
    13         // 方法声明:使用ref关键字声明引用形参
    14         void MyMethod(ref MyClass f1, ref int f2)
    15         {
    16             f1.val += 5;
    17             f2 += 5;
    18         }
    19     }
    20 
    21     class MyClass
    22     {
    23         public int val = 20;
    24     }

        下图说明上面方法调用过程:

      

      5.输出参数

        输出参数用于从方法体将数据传出到调用代码。输出参数的使用方式:第一,在声明和调用方法的时候都必须使用output修饰符;第二,实参必须是变量,该变量没有必要赋值,因为它会在方法体内部赋值,然后传出方法。int类型的TryPase方法就是一个使用输出参数的典型例子: public static bool TryParse(string s, out int result);

        下面是使用输出参数改写上面方法的示例:

    View Code
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             var p = new Program();
     6             MyClass a1 = null;
     7             int a2;
     8             // 方法调用:使用out修饰符传递实参          
     9             p.MyMethod(out a1, out a2);
    10         }
    11 
    12         // 方法声明:使用out修饰符声明输出形参
    13         void MyMethod(out MyClass f1, out int f2)
    14         {
    15             // 在方法体内部为输出参数赋值
    16             f1 = new MyClass();
    17             f1.val = 5;
    18             f2 = 10;   
    19         }
    20     }
    21 
    22     class MyClass
    23     {
    24         public int val = 20;
    25     }

        下图是该示例执行过程的说明:

      

      6.命名参数

        从参数的位置方面来讲,至此,我们使用的参数的每个形参和实参的位置都是一一对应的,这称为位置参数。位置参数是默认的参数形式。C#4.0中提出了命名参数的概念:命名参数在方法声明中的形参列表和位置参数一样,没有什么变化;在方法调用的时候,采用“形参名:实参值”的形式指定参数的名字,就可以以任意的顺序在方法调用的参数列表中列出实参。在方法调用中,可以将位置参数和命名参数混合使用,但所有位置参数必须在命名参数之前列出。 

    View Code
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             var p = new Program();
     6             MyClass a1 = new MyClass();
     7             int a2 = 10;
     8             // 方法调用:使用命名参数        
     9             p.MyMethod(f2: a2, f1: a1);
    10 
    11             // 方法调用:位置参数和命名参数混合使用,但是位置参数必须在命名参数之前。
    12             p.MyMethod(a1, f2: a2);
    13 
    14         }
    15 
    16         // 方法声明:使用默认的位置参数
    17         void MyMethod(MyClass f1, int f2)
    18         {                     
    19             f1.val += 5;
    20             f2 += 10;
    21         }
    22     }
    23 
    24     class MyClass
    25     {
    26         public int val = 20;
    27     }

      7.可选参数

        C#4.0引入了可选参数:就是在方法声明的时候使用初始化变量的方法为参数提供默认值,而在方法调用的时候,既可以包含该参数,也可以省略它。可选参数的使用条件:第一,可选参数的类型必须为值类型或者值为null的引用类型;第二,可选参数必须在所有必填参数之后,如果有params参数,必须在可选参数之后。下面是可选参数的示例:

    View Code
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             var p = new Program();
     6             MyClass a1 = new MyClass();
     7             int a2 = 10;
     8             // 方法调用:为可选参数f2提供显式值       
     9             p.MyMethod(a1, a2);
    10 
    11             // 方法调用:使用可选参数的默认值。
    12             p.MyMethod(a1);
    13 
    14         }
    15 
    16         // 方法声明:为int类型的参数f2提供默认值
    17         void MyMethod(MyClass f1, int f2 = 5)
    18         {
    19             f1.val += 5;
    20             f2 += 10;
    21         }
    22     }
    23 
    24     class MyClass
    25     {
    26         public int val = 20;
    27     }

      8.参数数组

        从参数的个数来讲,前面所列出的所有参数类型都是一个形参对应一个实参。而参数数组就是:零个或多个实参对应一个特殊的形参。参数数组的使用条件:

    一个参数列表中只能有一个参数数组;如果有,它必须是参数列表中的最后一个参数。

        1).参数数组的声明方式:第一,在参数的数据类型前面使用params修饰符。第二,参数声明为数组变量。下面是一个使用参数数组声明的方法示例:

    View Code
     1     class MyClass
     2     {
     3         // 使用参数数组声明一个方法
     4         public void ListInts(params int[] intVals)
     5         {
     6             if (intVals != null && intVals.Length > 0)
     7             {
     8                 foreach (var item in intVals)
     9                 {
    10                     int x = item * 10;
    11                     Console.WriteLine("X = {0} ", x);
    12                 }
    13             }
    14         }
    15     }

        2).带参数数组的方法的调用方式:

          有两种方式调用带参数数组的方法:第一种,使用一个用逗号表达式分隔的与参数类型相匹配的元素列表。第二种,使用一个与参数类型相匹配的元素的一维数组。下面是一个使用两种方式调用上面上面的带参数数组的方法的示例:

    View Code
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             var a1 = new MyClass();            
     6             int x = 1, y = 2, z = 3;
     7             // 调用方式一:使用一个用逗号表达式分隔的int型元素的列表。
     8             a1.ListInts(x, y, z);
     9             Console.ReadKey();
    10 
    11             // 调用方式二:使用一个int类型元素的一维数组。
    12             int[] arr = { 1, 2, 3 };
    13             a1.ListInts(arr);
    14             Console.ReadKey();
    15         }
    16     }

     二、方法重载

      1.什么是方法重载?

        方法重载就是在一个类中声明一个以上具有不同签名的同名方法。方法重载的目的:解决方法的重名问题,提高方法的可用性。

        方法签名的组成:方法名、参数类型、参数个数、参数顺序和参数的修饰符。注意:方法的返回值类型和方法的形参名称并不是方法签名的一部分。

      2.示例

        下面的类中声明了三个具有不同签名的同名方法,构成了方法重载。

    View Code
     1     class MyClass
     2     {
     3         // 1.使用参数数组声明一个名为ListInts的方法
     4         public void ListInts(params int[] intVals)
     5         {
     6             if (intVals != null && intVals.Length > 0)
     7             {
     8                 foreach (var item in intVals)
     9                 {
    10                     int x = item * 10;
    11                     Console.WriteLine("X = {0} ", x);
    12                 }
    13             }
    14         }
    15 
    16         // 2.重载1:声明了普通string数组类型的形参
    17         public void ListInts(string[] vals)
    18         {
    19             string result = string.Empty;
    20             foreach (var item in vals)
    21             {
    22                 result += item;
    23             }
    24             Console.WriteLine(result);
    25         }
    26 
    27         // 重载2:声明了string类型形参
    28         public string ListInts(string s)
    29         {
    30             return s + "......";
    31         }
    32 
    33       }

    三、递归

      方法递归就是方法自己调用自己。方法递归在为树绑定数据和无限级分类的设计当中用得比较多,是一种很优雅 解决方案。在现实生活中,有老和尚给小和尚讲故事的例子(从前有座山......),它就是一个典型的递归。

      下面是一个采用了递归的方式计算整数i的阶乘的方法:

    View Code
     1         // 计算i的阶乘
     2         public int Factorial(int i)
     3         {
     4             if (i<=1)
     5             {
     6                 return i;
     7             }
     8             // 采用递归
     9             return i * Factorial(i - 1);
    10         }

      

  • 相关阅读:
    今天封装了一下 gridview 在没有数据的时候显示表头 并且提示数据为空的方法
    动态绑定treeview的方法
    Android为拨号盘dialer定制声音DTMF Tones
    如何降低android应用程序的耗电量
    DTMF双音多频按键信号的定义
    ant 实现批量打包android应用
    android网络编程——使用Android中的网络连接
    Android Service被关闭后自动重启,解决被异常kill 服务
    android中阿拉伯文研究
    android网络编程——http get
  • 原文地址:https://www.cnblogs.com/sunyunh/p/2841507.html
Copyright © 2020-2023  润新知