Home [C# 筆記] out 參數
Post
Cancel

[C# 筆記] out 參數

三個高級的參數

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;
    }
}
This post is licensed under CC BY 4.0 by the author.