REF

Method Parameters

详述C#中out和ref有哪些差异及优势

C#中in,out,ref,params的作用和区别

Method Parameter

在一般情況下所有的輸入參數(argument) 都是傳值(value), 表示會傳入 variable 的副本

  • 在 value type 的情況下 variable 的 value 會被複製並傳入 method

  • 在 reference type 的情況下, variable 的 reference(也就是 address) 會被複製並傳入 method

在 variable 是 value type 的情況下, 如果需要傳入 value type variable 的 reference(variable address) 則需要添加修飾符 ref, out, in

Ref

ref 在 method 宣告, 呼叫時皆須使用

傳遞給 ref參數(argument) 的 variable 在 method 調用前需要先初始化(initial), 即必須已經賦值

method 內部可以 read 和 update ref argument 的 value, 即原本的 variable 的 value 會變更

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
static void Main(string[] args)
{
    int ref_num = 10; // 需要先給 value

    AddNumber(ref ref_num); // 使用 method 傳入 argument 時, 要同時使用 modifier

    Console.WriteLine(ref_num); // output 20

    Console.ReadKey();
}

static void AddNumber(ref int number1)
{
    number1 += 10;
}

Out

out 在 method 宣告, 呼叫時皆須使用

傳遞給 out argument 的 variable 在 method 呼叫之前不須先初始化(initial), 只需要宣告 type, 即使預先給定 value 也沒有意義, 因為 method 內部會對 variable 重新賦值

method 內部必須對 out argument 賦值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
static void Main(string[] args)
{
    int out_num; // 宣告 type
    // int out_num = 100; // 給定 100 也無效果

    AddNumber(out out_num); // 使用 method 傳入 argument 時, 要同時使用 modifier

    Console.WriteLine(out_num); // output 15

    Console.ReadKey();
}

static void AddNumber(out int number1)
{
    number1 = 5; // method 內部會賦值
    number1 += 10;
}

In

in 在 method 宣告時需要設定, 呼叫時不需要

傳入的 value 無法被修改, 只能是 read only, 但好處是可以不用 copy 副本, 而是直接使用 address, 可以減少 memory 消耗

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
static void Main(string[] args)
{
    int in_num = 10;

    PrintNumber(in in_num); // method 傳入 argument 時, 可以不使用 modifier(in)

    Console.ReadKey();
}

static void PrintNumber(in int number1)
{
    // number1 += 10; // 編譯錯誤, 不能修改 in argument 的 value
    Console.WriteLine(number1); // 儘可以讀取
}

ref 和 out 差異

Ref

  • Reference Passing:表示傳遞的是 argument 的引用, method 內部對該 argument 的修改會影響原 argument(variable) 的 value

  • Intial 要求:傳遞給 ref argument 的 variable 在 method 呼叫之前必須已經 initial(即已賦值)

  • RW 能力:method 內部可以 read 和 write ref argument 的 value, method 內對 ref argument 的任何變更都會反映在 variable 上。

Out

  • Output argument:Out 表示傳遞的是 argument 的引用, method 內部對該 argument 的賦值會影響原 argument(variable) 的 value

  • Intial 要求:傳遞給 out 參數的變數在方法呼叫之前不需要 Initial, 只需宣告 type 即可

  • 賦值要求:method 內部必須對 out argument 進行賦值, 確保在方法傳回之前該 argument 已經被賦值

  • RW 能力:method 內部只能寫入 out argument 的 value, 讀取 out argument 的 value 是未定義的, 必須在 method 內部賦值後才能讀取