C#的代码包装
三种实现途径:方法、类 和名字空间。
• 方法是包含一系列语句的代码块。
• 类用于组合类,方法,属性。
• 将多个相关类组合成名字空间。
静态方法和静态变量
• 静态成员
在类中,使用static修饰符声明的成员称为静态成员(包括静态 变量和静态方法)。
静态成员属于类成员,其访问形式为:
类名.静态成员名或 静态成员名(在本类的成员方法中 )
• 静态变量
使用static修饰的字段(域)称为静态变量。
类中的静态变量仅分配一块存储区域。
静态变量在整个程序运行期间都是存在的(静态变量不能被撤销)。
• 静态方法
使用static声明的方法称为静态方法。
静态方法只允许访问类的静态成员,而不允许访问其非静态成员------ 即实例成员。
非静态方法可以访问类中的任何成员(包括静态成员和非静态成员)。
方法参数修饰符
• 方法中的参数分为值参数和引用参数。
对应四种修饰:ref,out, params和无修饰符(默认)。
无修饰符的参数和params参数-按值方式传递
ref和out修饰的参数-按引用方式传递
1. 值参数(即无任何修饰符标记的参数)
值参数采用值方式传递(即默认的传递方式)。
值传递是指在进行方法调用时,系统将实参的值(包括引用变量的值) 复制给形参变量(这时,形参实际是实参值的一个副本)。
方法中使用和修改的是"副本",并不影响实参的值。
值传递是一种安全的传递方式。
2. 引用参数(使用ref修饰符标记的参数)
引用参数采用引用传递。
引用传递是将实参的引用(即实参变量的地址)复制给形参,这 时,形参作为实参的别名与实参共享同一内存单元。
方法中使用形参就如同使用实参,形参值变了,实参值也就变了。
3. 输出参数(使用out修饰符标记的参数)
输出参数与引用参数类似,也是采用引用传递。
在C#中,通过设置输出参数,可从方法中传回更多的数据值。
与引用参数不同,out实参变量可以不提供初值。
注意:
对于输出参数,形参和实参都必须用out进行标识。
out实参在方法调用前不必赋以初值,但在方法中必须为out形参提供数 据值(作为该参数的返回值)
参数传递的隐式转换与强制转换
• 方法调用中,若实参值与形参类型不同,默认情况下系统会依照"类型转 换规则"隐式地将实参值转换成形参类型传递给形参。
• 例如:Math类的方法Sqrt,参数声明为double型,但可以使用整型参数调 用。Console.WriteLine(Math.Sqrt(9));
• 能正确求值,输出值为3.0。
• 在C#中,系统会依照"类型转换规则"隐式地将int值9转换成9.0,然后传 入Sqrt方法
方法重载
• 方法重载
可定义两个或两个以上的同名方法,这些方法可以完成不同的功能, 编译器能根据方法的调用形式合理选择一个方法进行调用。
• 构成重载的方法具有以下特点:
(1)方法名相同;
(2)方法参数列表不同,即满足如下三点之一即可。
方法参数数目不同;
方法拥有相同数目的参数,但参数的类型不一样;
方法拥有相同数目的参数和参数类型,但是参数类型出现的先 后顺序不一样。
特别提醒:构成重载的方法与方法的返回值类型无关
可选参数和命名参数
1. 可选参数(即带有默认值的形参)
是指在声明方法时给形参指定默 认初值,这样在调用该方法时可省略实参。
public static int Days(int day,int month,int year=2015) { ... }
其中:形参year为可选参数,默认初值是2015。
例如: 方法调用-Days(18,2) 方法调用-Days(18,2,2014)
说明:可选参数必须位于所有必选参数之后,即可选参数出现在 参数列表的右端
2. 命名参数
是指调用方法时,可为实参指定一个形参名,作用是将该实参传 递给指定的形参,这样参数结合时与参数位置次序无关。
形式为:形参名:实参
如:使用命名参数调用Days方法:
Days(month:2,day:18)
Days(year:2015,month:2,day:18)
按值传递与按引用传递
• 值类型参数不都是按值方式传递,引用类型参数也并非都是按引用方式传递。
例如:
方法声明1:public void Test1(int a){...} 形参a是整数类型,属于值类型。
方法声明2:public void Test2(int[] array){...} 形参array是数组,属于引用类型。
但它们的传递方式相同,均采用"按值传递"。
.NET 框架类库
• .NET框架类库(即FCL)是生成.NET 应用程序、组件和控件的基础。
• .NET框架类库由多个预定义的名字空间构成,而每一个名字空间又是由预 定义的多个相关的类组成。
• 名字空间中类型使用点语法命名方案,全名的第一部分(最右边的点之前 的内容)是名字空间名。全名的最后一部分是类型名。
例如,System.Console表示Console类型,该类型属于System名字空间。
使用using指令时后,当使用FCL中的库类时,可不必指定名字空间名。
例如,程序中使用如下指令:using System;
程序使用System名字空间中类(如Console)时,可省略该名字空间名,而直接使 用类名。
如:Console.Writeline(); 与 System.Console.Writeline();等价。
声明的作用域
• 方法参数声明的作用域是声明所在的方法体。
• 局部变量的声明的作用域从声明点开始,到声明所在块结束为止。
• for语句首部的局部变量声明的作用域是for语句体和首部的其他表达式。
• 类中成员(如方法、属性、字段)的作用域是整个类体。因此类的非静 态方法与属性可以使用类中的任何成员,而静态方法与属性只能使用类 中的静态成员。
另外,在类的声明中,如果方法中的局部变量或参数与方法所在类中的 字段名同名,则在方法中将隐藏该字段。但可通过this.字段名的形式使 用实例中的字段。
递归
递归是计算机科学的一个重要概念,递归方法是程序设计中有效的方法,采用 递归编写程序能使程序变得简洁和清晰。
• 利用递归算法可以将一个规模较大的问题转化为规模较小的同类问题 来求解。
例如:数学上常见的一个问题-计算一个非负整数n!
计算n!,只要计算出(n-1)!,则n!=n.(n-1)! 计算(n-1)!,只要计算出(n-2)!,则(n-1)!=(n-1).(n-2)! 计算(n-2)!,只要计算出(n-3)!,则(n-2)!=(n-2).(n-3)! ... 计算3!,只要计算出2!,则3!=3.(2!) 计算2!,只要计算出1!,则2!=2.(1!) 而1!=1 (注:0!定义为1)