#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 ////////////////////////////////////