方法是一种组合一系列语句以执行一个特定操作或计算一个特殊结果的方式。
它能够为构成程序的语句提供更好的结构和组织。
在面向对象的语言中,方法总是和类关联在一起的,我们用类将相关的方法分为一组。
方法通过参数来用于从调用者向目标方法传递数据的变量。
方法也通过一个返回值将数据返回给调用者
一个方法调用由以下元素构成:命名空间、类型名称、方法名称、参数以及返回数据类型。
1、命名空间
命名空间是一种特殊的分类机制,它将与一个特定功能有关的所有类型都分组到一起。
编译器认为所有命名空间都在同一个级别上。所以需要分别引用。
不会因为两个命名空间的包含关系,而将其认为是一个命名空间,而是两个完全独立、完全不同的命名空间。
用方法进行重构
将一组相关的语句转移到一个方法中,而不是随意将它们嵌入一个较大的方法中,
中重构的一种形式。重构有助于减少重复代码。
return语句意味着跳到方法的末尾。
using指令(导入命名空间,或者命名空间中的类型)
可以将来自一个命名空间的类型导入父命名空间代码块中。
虽然命名空间是嵌套的,但是using不会导入任何嵌套的命名空间,嵌套的命名空间需要单独的
显式地导入。
注:
使用using System后,可以使用不同的大小写形式来表示字符串数据类型:String string
前一个版本依赖using System指令,后一个重酬使用string关键字。
两者在C#中都合法地引用了System.String数据类型,最终生成 的CIL代码毫无区别。
using 可以出现在任何一个地方,但是其作用域与其放置的的地方的作用域相同。
使用别名
using a1=System.Threading;
2、调用者和调用栈
代码执行时,方法可能调用其他方法,其他方法可能调用更多的方法。
调用嵌套调用的情况会形成调用栈,随着程序复杂程序的提高,每个方法调用另一个方法时
,这个调用栈都会变大。然后当调用结束时,调用栈会发生收缩,直到调用另一系列的方法。
栈展开:用来描述从调用栈中删除调用的过程。
栈展开的顺序通常与方法调用的顺序相反。
一个方法调用完毕之后,会将控制权返回给调用点,也就是最初发出方法调用的那个位置。
3、参数
值参数
参数默认是传值的。变量的栈数据会完整地复制到目标参数中。
无论传递的实际参数是值类型还是引用类型。
都不能修改原来的实际参数的值。(值类型不会改变原来的实际数据值,引用类型不能修改实际
参数的指向,但是可以改变指向的实际数据的值)
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 int x = 0; 6 Program p = new Program(); 7 p.ChangeValue(x, p); 8 Console.WriteLine("x=" + x + ",p.count=" + p.count); 9 Console.ReadLine(); 10 11 12 } 13 public void ChangeValue(int pValue,Program p) 14 { 15 int temp = pValue; 16 pValue = 10; 17 p.number = 10; 18 p.count = 10; 19 p = new Program(); 20 p.count = 20; 21 22 } 23 public int number = 0; 24 public int count = 0; 25 }
输出:
x=0,p.count=10
引用参数
使用ref修饰
无论传递的实际参数是值类型还是引用类型。
都可以修改原来的实际参数的值。(值类型会改变原来的实际数据值,引用类型不仅能修改实际
参数的指向,还可以改变指向的实际数据的值)
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 int x = 0; 6 Program p = new Program(); 7 p.ChangeValue(ref x, ref p); 8 Console.WriteLine("x=" + x + ",p.count=" + p.count); 9 Console.ReadLine(); 10 11 12 } 13 public void ChangeValue(ref int pValue,ref Program p) 14 { 15 int temp = pValue; 16 pValue = 10; 17 p.number = 10; 18 p.count = 10; 19 p = new Program(); 20 p.count = 20; 21 22 } 23 public int number = 0; 24 public int count = 0; 25 }
输出:
x=10,p.count=20
输出参数
使用out修饰
如果一个参数被标记为out,编译器就会核实在方法的所有正常返回代码路径中,是否
都对该参数进行了赋值。
参数数组
它允许在调用一个方法提供数量可变的参数,而不是由方法事先固定好参数的数量
1、在方法声明的最后一个参数之前,添加一个params关键字
2、将最后一个参数声明为一个数组
参数数组注意事项:
1、参数数组不一事实上是方法声明中的唯一参数。但是,参数数组必须是方法慢用中的最后一个参数
2、调用者可以为参数数组指定0个参数,也可以指定多个参数
3、类型必须匹配于数组指定的类型
4、调用者可以显式地使用一个数组,而不是以逗号分隔的参数列表。
使用参数数组,我们可以将相同类型的、数量可变的多个参数付给一个方法。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 string fullName; 6 fullName = Combine(Directory.GetCurrentDirectory(), "bin", "config", "index.html"); 7 Console.WriteLine(fullName); 8 fullName = Combine(new string[] { Directory.GetCurrentDirectory(), "bin", "config", "index.html" }); 9 Console.WriteLine(fullName); 10 Console.ReadLine(); 11 } 12 static string Combine(params string[] paths) 13 { 14 string result = string.Empty; 15 foreach (string path in paths) 16 { 17 result = System.IO.Path.Combine(result, path); 18 } 19 return result; 20 } 21 22 }
4.7方法重载
方法重载是一种操作性多态(编译时多态)
C#依据方法名、参数数据类型或者参数数量的不同来定义唯一性。
所以方法重载:方法名相同,参数数据类型或者参数数量不同。
4.8可选参数
通过在声明方法时,将常量赋值给参数,以后调用方法时就不必为此参数指定值。
必须从右向左实现可选参数。
C#4.0新增了另一个方法调用功能是命名参数,利用命名参数,调用者可显式指定参数名,并为该参数赋值
,而不是像以前那样只能依据参数顺序来决定哪个值赋值给哪个参数。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 string firstName = "aaaaa", middleName = "bbbbbbbbb", lastName = "cccccccc"; 6 string fullName; 7 fullName = Combine(firstName); 8 Console.WriteLine(fullName); 9 10 fullName = Combine(pfirstName: firstName,plastName:lastName); 11 Console.WriteLine(fullName); 12 13 fullName = Combine(pfirstName: firstName, pmiddleName: middleName); 14 Console.WriteLine(fullName); 15 16 Console.ReadLine(); 17 18 19 } 20 static string Combine(string pfirstName, string pmiddleName = ".", string plastName = "") 21 { 22 string result = pfirstName + pmiddleName + plastName; 23 24 return result; 25 } 26 27 }
4.9异常处理
try
throw
catch(多个
finally
一旦引发异常或者throw一个异常,后面的代码不会执行,会跳转到某个catch执行(可以有多个catch,有多个catch时,处理异常的类型从具体到到抽象依次顺序声明),
并且finally会永远执行,无论引发异常与否。