方法的组成 方法一般是由三部分组成。即方法名,参数,方法体。
在下面的代码里
handler  – 方法名
c  – 参数(可传可不传)
return  – 后跟返回值(可返回可不返回)
方法名前面的类型  – 返回值类型
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 using  System;class  Test  {  static  public  int  handler0 () {}    static  public  int  handler ()   {     int  a = 1 ;     int  b = 2 ;     return  a + b;   }   static  public  int  handler1 (int  c = 2  )   {     int  a = 1 ;     int  b = 2 ;     return  a + b + c;   } } class  Program  {    static  void  Main (string [] args )  {         Console.WriteLine("Hello, world!" );       Test.handler0();        int  res = Test.handler();        Console.WriteLine(res);       int  res1 = Test.handler1();        Console.WriteLine(res1);     } } 
 
方法体 变量 方法里的变量被称为本地变量。存在生命周期。
本地常量  和变量相对应,区别是:只能在声明的时候赋值一次。后面不能改变。
 const 要加在类型前面
 const 有点像一个修饰符
1 2 3 4 5 关键字   | const  int  Identifier = Value;												 |                       初始化的值是必须的 
 
块 块中存在生命周期,当块中的代码执行结束后,所有声明的变量都会被销毁。
如果变量在栈里,会被踢出。
 
一个执行体,可以去嵌套。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class  Test  {  static  public  int  handler1 (int  c = 2  )   {     int  a = 1 ;     int  b = 2 ;     {       Console.WriteLine("1111: {0}" , a + b);       var  d = a + b;       {         Console.WriteLine("1111: {0}" , d);       }     }     return  a + b + c;   } } 
 
可以使用 var  去声明变量 ,前提是一个可以推断出类型的变量。
c#的静态编译器,从右往左执行代码,同时可以推断出变量的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 using  System;class  Test  {  static  public  int  handler1 (int  c = 2  )   {     int  a = 1 ;     int  b = 2 ;     return  a + b + c;   } } class  Program  {    static  void  Main (string [] args )  {       var  res1 = Test.handler1();       Console.WriteLine(res1);     } } 
 
控制流(代码执行顺序) 
代码总不是顺序执行的,所以我们需要其他的执行方式。譬如跳转、循环、条件==。
 
顺序执行
条件执行
 if
 if…else
 switch
循环
 for
 while
 do
 foreach
跳转语句
 break
 continue
 goto
 return
参数 参数定义 实参 实参类型(取决于参数数据类型) 	不同类型的实参,实际产生的效果不同。对于普通整型参数传入时,属于值传入,方法执行的时候会复制一份,不会改变原始值。而参数数组值时,输入引用传入,方法执行传入的是一个引用,方法执行完成,如果有改变形参,则会改变原始值。
形参  形参是本地变量;
 调用方法的时候,在代码执行前形参完成初始化;
值参数 值参数取决于参数类型,对于简单类型,那么则是值传递,对于复杂类型则类似下面说道的引用参数。
引用参数 类似于引用传递,会修改原始值。
由于形参名和实参名的行为就好像指向相同的内存位置,所以在方法的执行过程中对形参作 的任何改变在方法完成后依然有效(表现在实参变量上)。
可以强行把简单类型的数值换为引用参数,只需要通过修饰符去修饰即可。
声明和调用中都需要使用ref修饰符 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public  void  fn5 (ref  int  f1 )  {	f1 = f1 + 2 ; } var  argsIns = new  Args();var  refParam = 4 ;Console.WriteLine(refParam); argsIns.fn5(ref  refParam); Console.WriteLine(refParam); 
 
输出参数 输出参数用于从方法体内把数据导出到调用代码
声明和调用中都需要使用out修饰符 
和返回值毫无关系
可以有多个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class  Args  {     public  void  fn2 (out  int  x, params  int [] args )  {     x = 1 ;   } } ... int  paramOut;argsIns.fn2( out  paramOut, paramList); Console.WriteLine("{0}" , paramOut); 
 
参数数组  常规参数
 形参,实参一一对应
 参数数组的特点
 参数无需对应,但是参数数组需要保持相同的类型
 通过 params 关键字去修饰为参数列表形式
实参可以传入一个数组类型(如果是数组的话,则类似于引用传递)
实参也可以传入一组数据
1 2 3 4 5 6 7 8 9 static  public  void  fn2 (params  int [] args ) {   Console.WriteLine(args[0 ]); } int [] arr = {1 ,2 ,3 ,4 };fn2(arr);  fn2(1 ,2 ,3 ,4 ,5 ,6 );  
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class  Args  {     static  void  Main (params  int [] args )  {     Console.WriteLine("111" );   }   public  void  fn1 (params  int [] args )  {     if  ((args != null ) && (args.Length != 0 ))     {       for (int  i = 0 ; i < args.Length; i++) {         args[i] = args[i] * 10 ;         Console.WriteLine("{0}" , args[i]);       }     }   } } class  Program  {    static  void  Main (string [] args )  {         var  argsIns = new  Args();         int  params1 = 1 , params2 = 2 , params3 = 3 ;         argsIns.fn1(params1,params2,params3);         Console.WriteLine("{0}, {1}, {2}" , params1, params2, params3);          Console.WriteLine("=========================" );                int [] paramList = {1 ,2 ,3 };         argsIns.fn1(paramList);         foreach (int  x in  paramList)           Console.Write("{0}, " , x);      } } 
 
具名参数(named parameter) 在调用方法的时候,可以给参数具名,语法看上更加直观。
可选参数(optional parameter) 参数需具有默认值
如果一个参数具有默认值,那么这个参数可以作为可选参数,可选参数的话,就是这个参数可传递可不传递。
如果存在必传参数,那么可选参数应该放在必传参数之后
方法重载(method overload) 
和继承里的方法重写(method override) 不同
 
一个类中可以有一个以上的方法拥有相同的名称,使用相同名称的方法必须要有一个和其他方法不同的形式,这个叫做签名(signature) 。
方法的签名可以由下列信息组成。
方法名称 
参数的数目 
参数的数据类型和顺序 
参数的修饰符 
 
以上如果不满足任意一条,则重载声明成功,否则失败。
递归 1 2 3 4 5 6 7 8 9 10 11 12 13 static  public  int  Factorial (int  Value )  {      if  (Value <= 1 )         return  Value;       else          return  Factorial(Value - 1 ) * Value;     } Console.WriteLine(Factorial(4 )); 
 
总结 签名 是重要的,它描述了重载的可能。
C#的方法(函数)玩法是很多的,一个参数都有输入输出,参数列表等。其实在JS中,没有参数输出的概念,其实个人感觉也是很无必要,因为之前用JS也没觉得是必要的。反而参数列表来说,JS是在ECMA2015中实现的。但它不是直接在函数里去扩展,而是通过一个新的语法形式,扩展运算符(spread operator)。从个人理解上来说,参数列表更像是语法糖,而非语法。所以更推崇JS里的实现形式。同时还有一点,在C#的参数列表里,如果方法定义了参数列表,那么实参可以是一个array 也一可以正常的一串参数,这里感觉会有歧义。但在JS里不会,始终是一串参数,只是可以扩展运算符去解释。
具名参数的可玩性很高啊!JS里没有实现这个,哈哈。