C#方法

  • A+
所属分类:.NET技术
摘要

继续填坑复习,上次讲完类型和变量,这次讲讲方法。
方法(method)的前身是C/C++语言的函数(function)。方法是面向对象范畴的概念,在非面向对象语言中仍然称之为函数。方法永远都是类或结构体的成员,C#语言中函数不可能独立于类或结构体之外,只有作为类或者结构体的成员时才能被称为方法。方法是类或结构体最基本的成员之一(最基本的成员只有两个——字段和方法,本质上是数据+算法)。


C#入门笔记

继续填坑复习,上次讲完类型和变量,这次讲讲方法。
方法(method)的前身是C/C++语言的函数(function)。方法是面向对象范畴的概念,在非面向对象语言中仍然称之为函数。方法永远都是类或结构体的成员,C#语言中函数不可能独立于类或结构体之外,只有作为类或者结构体的成员时才能被称为方法。方法是类或结构体最基本的成员之一(最基本的成员只有两个——字段和方法,本质上是数据+算法)。

方法的声明与调用

C#中的方法要在类或者结构体里面声明,所以声明的时候要留意位置对不对,不要在名称空间里面声明,会报错的。C#的方法声明和C差不多,访问修饰符+返回值类型+方法名+参数列表。下面看一段代码:

using System;  namespace SomeNotes {     class Program     {         public static void Main(string[] args)         {             int a = 1, b = 2;             int result = Add(a, b);             Console.WriteLine(result);              Printer printer = new Printer();             printer.SayHello();         }          public static int Add(int a, int b)         {             return a + b;         }     }      class Printer     {         public void SayHello()         {             Console.WriteLine("Hello World!");         }     } } 

第17行我声明了一个叫Add的方法,用static是为了不实例化就使用它,如果一个方法没有带访问修饰符的话,它默认会给你一个internal的访问权限,意思就是在同一个程序集里面可见。后面的int就是返回一个整数类型的值,括号里面的就是参数列表了,两个int类型的参数。进入函数体里面,返回一个a + b的值,函数的声明就完成了。
回到Main函数里面,第10行调用了Add,把 a 和 b 的值传进Add中,然后返回值赋给result,最后打印result的值为3。
上面讲的是静态方法,用static修饰的方法就是静态方法,指的是不用实例化就能使用。下面还有一个叫SayHello的方法,它的访问修饰符是public,返回值为void(没有返回值,这类方法一般是执行一些操作),参数列表为空。进入方法体内,它只干了一件事,打印一行字。
再回到Main函数里面,第13行我用一个Printer类型的变量printer去引用一个Printer的实例,然后调用printer里面的方法,也就是SayHello,控制台就会打印一行“Hello World!”。
静态成员在类的第一次加载的时候就全部加载出来了,所以静态方法不需要实例化也能调用;后面的SayHello则不能直接调用,要先声明一个实例,然后通过实例去调用。
函数的参数叫做形式参数(parameter),传入函数的参数(不是在函数里面声明的)叫做实际参数(argument),如果形参不带refout修饰符,那么它的值的变化不会影响实参,它相当于实参的一份copy,就算它们同名,一样不会有影响。

引用参数和输出参数

先上一段代码吧,看着代码来解释。

using System;  namespace SomeNotes {     class Program     {         public static void Main(string[] args)         {             int max, min = 0, sum = 0;             int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };             double ave = 0;              Calculator calc = new Calculator();             calc.GetStatistics(nums, out max, min, ref ave, ref sum);              Console.WriteLine(max);             Console.WriteLine(min);             Console.WriteLine(sum);             Console.WriteLine(ave);         }     }      class Calculator     {         public void GetStatistics(int[] array, out int max, int min, ref double ave, ref int sum)         {             max = array[0];             min = array[0];             sum = 0;             for (int i = 0; i < array.Length; i++)             {                 if (array[i] > max)                 {                     max = array[i];                 }                 if (array[i] < min)                 {                     min = array[i];                 }                 sum += array[i];             }             ave = (double)sum / (double)array.Length;         }     } } 

有点长,但是不要怕,一个个来看。GetStatistics这个方法它干了四件事,算出最大值、最小值、平均值和总和,注意看参数列表里面,array是一个整数类型的数组,max的前面除了int,还多了一个out,带着out修饰的参数就是输出参数。先继续看,min是一个整数类型的形参,avesum都带着ref,这个两个都是引用参数。
先说说引用参数,引用参数使用的时候要在类型前加上ref,方法的声明和调用都要带上ref。引用参数的作用是实参的值会传入形参中,形参在方法体内进行一系列的操作之后,它的值会返回给实参,就是说形参的改变会引起实参的改变。拿上面的程序来说,avesum打印出来的结果是5.5和55。值得注意的是第42行中,sumarray.Lenghth经过了强制类型转换从int转换为double再进行除法运算。尽管在Main函数中,maxsum的值被初始化为0,但是引用参数会改变实参的值。
与之相似的就是输出参数了,带上out的就是输出参数。既然是类似,我们就对比着来说,在方法的声明和调用时,输出参数都要带上out。与引用参数不同的是,输出参数只会输出:在方法内进行一系列操作后,输出参数的值会返回给对应的实参;实参是否初始化不影响输出参数的使用,因为输出参数规定要在方法体内初始化,比如第27、29行,所以你实参是否进行初始化并不影响使用,也不会报错。看上面的程序,max就是输出参数,最后打印的结果为10。
下面最关键的来了,min会打印出什么呢?1吗?肯定不是。实参min的默认值为0,方法体中的形参被初始化为array[0],在方法体内最后形参min的值肯定是1,但是,这个值会返回给实参min吗?不会的,因为它既不是引用参数,也不是输出参数,所以形参的值无法传给实参,最终打印出min的结果为0。
有一点C基础的人肯定知道怎么去把形参的值返回给实参——指针,但是C#不推荐你使用指针,把指针设为了“不安全代码”,所以大家要把形参实参挂钩的话,多用输出参数和引用参数吧。

方法的调试百度吧,逐语句跟踪变量,yyds

后续coming soon...(perhaps)