C#基础-第9章:参数
说明:第2部分:第9章:参数P(185)
8.1 本章内容:
- 可选参数和命名参数
- 隐式类型的局部变量
- 以传引用的方式向方法传递参数,out,ref
- 向方法传递可变数据量的参数:params
- 参数和返回类型的设计规范:传入弱类型,返回强类型。
- 常量性
#define V1 //#define V2 //#define V3 using System; using System.Collections.Generic; public static class Parameters { public static void Main() { OptionalAndNamedParameters.Go(); MethodsThatTakeVariableArguments.Go(); OutAndRefParameters.SomeMethod(); } } internal static class OptionalAndNamedParameters { private static Int32 s_n = 0; public static void Go() { ImplicitlyTypedLocalVariables();//P(185) //1.等同于: M(9, "A", default(DateTime), new Guid()); M(); // 2. 等同于: M(8, "X", default(DateTime), new Guid()); M(8, "X"); // 3. 等同于: M(5, "A", DateTime.Now, Guid.NewGuid()); M(5, guid: Guid.NewGuid(), dt: DateTime.Now); // 4. 等同于: M(0, "1", default(DateTime), new Guid()); //PS:s_n 先传值,再++ M(s_n++, s_n++.ToString()); // 5. 等同于: String t1 = "2"; Int32 t2 = 3; // M(t2, t1, default(DateTime), new Guid()); M(s: (s_n++).ToString(), x: s_n++); } private static void M(Int32 x = 9, String s = "A", DateTime dt = default(DateTime), Guid guid = new Guid()) { Console.WriteLine("x={0}, s={1}, dt={2}, guid={3}", x, s, dt, guid); } private static void ImplicitlyTypedLocalVariables()//P(188) { /***************** 隐形类型的局部变量 **********************/ var name = "Jeff"; ShowVariableType(name); // 显示: System.String // var n = null; // 错误,不能将null赋给隐式类型的局部变量 var x = (Exception)null; // OK, 可以这样写,但是意义不大 ShowVariableType(x); // 显示: System.Exception var numbers = new Int32[] { 1, 2, 3, 4 }; ShowVariableType(numbers); // 显示: System.Int32[] // 复杂类型能少打些字 var collection = new Dictionary<String, Single>() { { ".NET", 4.0f } }; // 显示: System.Collections.Generic.Dictionary`2[System.String,System.Single] ShowVariableType(collection); foreach (var item in collection) { // 显示: System.Collections.Generic.KeyValuePair`2[System.String,System.Single] ShowVariableType(item); } } private static void ShowVariableType<T>(T t) { Console.WriteLine(typeof(T)); } } /// <summary> /// out ,ref参数的区别 /// </summary> internal static class OutAndRefParameters { #if V1 public static void Go() //P(190) { Int32 x; // x 没有初始化 SetVal(out x); // x 不必初始化, //out 在调前不需要初始化,而ref不需要,其实CLR是不区分out ref的。 Console.WriteLine(x); // 显示 "10" } private static void SetVal(out Int32 v) { v = 10; //该方法必须初始化 } #endif #if V2 public static void Main() //P(191) { Int32 x = 5; // x 已经初始化 AddVal(ref x); // X 必须初始化 Console.WriteLine(x); // 显示 "15" } private static void AddVal(ref Int32 v) { v += 10; // 该方法可以使用v的已初始化的值 } #endif #if V3 public static void Main() { Int32 x; // x没有有初始化 // 下一行代码无法通过编译,编译器将报告: // error CS0165: 使用了未赋值的局部变量 'x'. AddVal(ref x); Console.WriteLine(x); } private static void AddVal(ref Int32 v) { v += 10; // 该方法可以使用v的已初始化的值 } #endif //下面演示了如何用ref关键字实现一个用于交换两个引用类型的方法: public static void Swap(ref Object a, ref Object b) { Object t = b; b = a; a = t; } public static void Swap<T>(ref T a, ref T b) { T t = b; b = a; a = t; } #if true public static void SomeMethod()//P(193) { String s1 = "Jeffrey"; String s2 = "Richter"; Swap(ref s1, ref s2); // 这里调用不是上面的 Swap(object,object) 而是 Swap<T>,因为编译不通过, // PS: ref ,out 的参数类型必须和方法保持一致。SomeMethod2 才是正确的表达。 Console.WriteLine(s1); // 显示 "Richter" Console.WriteLine(s2); // 显示 "Jeffrey" } #endif public static void SomeMethod2()//P(194) { String s1 = "Jeffrey"; String s2 = "Richter"; // 以传引用的方式传递的变量, // 必须和方法预期的匹配 Object o1 = s1, o2 = s2; Swap(ref o1, ref o2); //这里调用才是 Swap(object,object) // 完事后再将object转型为String s1 = (String)o1; s2 = (String)o2; Console.WriteLine(s1); // 显示 "Richter" Console.WriteLine(s2); // 显示 "Jeffrey" } } internal static class MethodsThatTakeVariableArguments { public static void Go() { // 显示 "15" Console.WriteLine(Add(new Int32[] { 1, 2, 3, 4, 5 })); // 显示 "15" Console.WriteLine(Add(1, 2, 3, 4, 5)); // 显示 "0" Console.WriteLine(Add()); DisplayTypes(new Object(), new Random(), "Jeff", 5); } // params 参数为可以变数量参数的关键字 private static Int32 Add(params Int32[] values)//P(195) { // 注意:如果愿意,可以将values数组传给其它方法 Int32 sum = 0; for (Int32 x = 0; x < values.Length; x++) sum += values[x]; return sum; } private static void DisplayTypes(params Object[] objects) { foreach (Object o in objects) Console.WriteLine(o.GetType()); } } /////////////////////////////////////////////////////////////////////////////// public sealed class Point { static void Add(Point p) { /* ... */ } static void Add(ref Point p) { /* ... */ } //Add 不能定义仅在ref和out是有差别的重载的方法。 //下面这样不可以,不能这样重载. // static void Add(out Point p) { /* ... */ } } ////////////////////////////// End of File ////////////////////////////////////