三個高級的參數
out, ref, params
什麼是out參數?
幫助我們在一個方法中,可以返回多個不同類型的值回去。
什麼時候使用out參數呢?
如果在一個方法中,返回多個相同類型的值的時候,可以考慮返回一個陣列。
但是,如果想要返回多個不同類型的值的時候,返回陣列就不行了,
那麼這個時候,我們可以考慮使用out參數。
out參數就著重於在一個方法中,可以返回多個不同類型的值。
怎麼做呢?
寫一個void方法,先把要傳入的參數放進去,
現在要返回值,要怎麼做呢?使用out返回
在我們形參列表(參數列表),在方法聲明變量的前面加上out, 也就是方法參數的前面加上out
Step1. 先在形參列表裡面,用out參數寫上你要多個返回的那幾個值。
Step2. out參數要求在方法的內部,必須為其賦值。
為什麼要賦值?因為要返回值呀
out 參數的使用
舉例:計算一個數組的最大值、最小值、總和、平均值
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
沒有用out參數的寫法
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
int[] result = GetMaxMinSumAvg(nums);
Console.WriteLine($"最大值:{result[0]}\r\n最小值:{result[1]}\r\n總和:{result[2]}\r\n平均值:{result[3]}");
Console.ReadKey();
/// <summary>
/// 計算一個數組的最大值、最小值、總和、平均值
/// </summary>
/// <param name="nums">要計算的陣列</param>
/// <returns>返回一個陣列(最大值、最小值、總和、平均值)</returns>
public static int[] GetMaxMinSumAvg(int[] nums)
{
int[] result = new int[4]; //宣告一個要返回的陣列
//假設res[0] 最大值 res[1]最小值 res[2] 總和 res[3]平均值
result[0] = nums[0]; //max
result[1] = nums[0]; //min
result[2] = 0;//sum
for (int i = 0; i < nums.Length; i++)
{
//如果循環的元素,比我假定的值還大,就賦值給我的最大值
result[0] = result[0] > nums[i] ? result[0] : nums[i]; //max
//如果循環的元素,比我假定的值還小,就賦值給我的最大值
result[1] = result[1] < nums[i] ? result[1] : nums[i]; //min
result[2] += nums[i]; //sum
}
result[3] = result[2] / nums.Length; //avg
return result;
}
用out參數的寫法
計算一個數組的最大值、最小值、總和、平均值
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
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int max; //用來接收out的返回值,不必給值,因為out方法中會賦值
int min;
int sum;
int avg;
Test(nums, out max, out min, out sum, out avg);
Console.WriteLine("最大值{0} 最小值{1} 總和{2} 平均值{2}", max, min, sum, avg);
Console.ReadKey();
/// <summary>
/// 計算一個數組的最大值、最小值、總和、平均值
/// </summary>
/// <param name="nums">要計算的陣列</param>
/// <param name="max">返回最大值</param>
/// <param name="min">返回最小值</param>
/// <param name="sum">返回總和</param>
/// <param name="avg">返回平均值</param>
public static void Test(int[] nums, out int max, out int min, out int sum, out int avg)
{
//out參數要求在方法的內部,必須為其賦值。
max = nums[0]; //最大值,先給一個假定值
min = nums[0]; //最小值,先給一個假定值
sum = 0; //總和
//遍歷陣列的每一個元素
for (int i = 0; i < nums.Length; i++)
{
max = max > nums[i] ? max : nums[i]; //max與每個元素比較,比它大就賦值給它
min = min < nums[i] ? min : nums[i]; //min與每個元素比較,比它小就賦值給它
sum += nums[i]; //把每個元素加到總和變數中
}
avg = sum / nums.Length; //總和/元素的數量
}
- 調用out參數的方法,用來接收的變數,不必初始化給值。 為什麼不用給值,因為在out參數的方法內部己經賦值了。
- 接收的變數名,不一定要跟定義方法的參數名一樣(形參)
但你接收的變數名,一定要跟調用方法的引數名相同(實參)。 - out參數要求在方法的內部,必須為其賦值。
為什麼要賦值?因為要返回值呀
例如,我們再把剛剛的方法加上這幾個out參數
out string s, out bool b, out double d
在方法的內部就要給它賦值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//用來接收out的返回值
//不必初始化給值
//變數名不一定要跟方法的參數名一樣
int max99;
string s99;
bool b99;
double d99;
R.Test2(nums, out max99, out s99, out b99, out d99); //調用out參數的方法
//out參數的方法
public static void Test(int[] nums, out int max, out string s, out bool b, out double d) {
.....
//out參數要求在方法的內部,必須為其賦值。
s = "abc123";
b = true;
d = 12.34;
}
練習:使用out參數做登入
分別的提示用戶輸入用戶名和密碼
寫一個方法來判斷用戶輸入的是否正確
返回用戶一個登入結果,並且還要單獨的返回用戶一個登入訊息。
如果用戶名錯誤,除了返回登入結果外,還要返回一個”用戶名錯誤”,”密碼錯誤”
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
43
//提示用戶輸入
Console.WriteLine("請輸入帳號");
string username = Console.ReadLine()!;
Console.WriteLine("請輸入密碼");
string password = Console.ReadLine()!;
//調用out參數的方法
string message;
bool isLogin = IsLogin(username, password, out message);
//輸出結果
Console.WriteLine($"登入結果 {isLogin}");
Console.WriteLine($"登入訊息 {message}");
Console.ReadKey();
//定義out參數方法
/// <summary>
/// 判斷用戶登入是否成功
/// </summary>
/// <param name="username">帳號</param>
/// <param name="password">密碼</param>
/// <param name="message"> 多餘返回的登入訊息</param>
/// <returns>登入是否成功</returns>
public static bool IsLogin(string username, string password, out string message)
{
if (username == "admin" && password == "8888")
{
message = "登入成功";
return true;
} else if (username == "admin")
{
message = "帳號錯誤";
return false;
} else if (password == "8888")
{
message = "密碼錯誤";
return false;
} else
{
message = "未知錯誤";
return false;
}
}
練習:自己寫一個tryParse
bool result = int.TryParse(“123”, out num);
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
int num;
bool result = MyTryParse("123", out num);
Console.WriteLine(result);
Console.WriteLine(num);
/// <summary>
/// 自己寫一個tryParse:字串轉int
/// </summary>
/// <param name="s">要轉換的字串</param>
/// <param name="result">回傳轉換成功的數值,失敗就回傳0</param>
/// <returns>判斷結果</returns>
public static bool MyTryParse(string s, out int result)
{
result = 0; //out參數在方法內部一定要賦值
try
{
//可能會有異常的地方,用try-catch包起來
result = Convert.ToInt32(s); //轉換成功的話,就賦值給result
return true;
} catch
{
return false;
}
}