退出

refout 關鍵字導致引數通過引用傳遞,而不是通過值傳遞。對於值型別,這意味著被呼叫者可以更改變數的值。

int x = 5;
ChangeX(ref x);
// The value of x could be different now

對於引用型別,變數中的例項不僅可以修改(沒有 ref 的情況),但它也可以完全替換:

Address a = new Address();
ChangeFieldInAddress(a);
// a will be the same instance as before, even if it is modified
CreateANewInstance(ref a);
// a could be an entirely new instance now

outref 關鍵字之間的主要區別在於 ref 要求變數由呼叫者初始化,而 out 將該責任傳遞給被呼叫者。

要使用 out 引數,方法定義和呼叫方法都必須明確使用 out 關鍵字。

int number = 1;
Console.WriteLine("Before AddByRef: " + number); // number = 1
AddOneByRef(ref number);
Console.WriteLine("After AddByRef: " + number);  // number = 2
SetByOut(out number);
Console.WriteLine("After SetByOut: " + number);  // number = 34

void AddOneByRef(ref int value)
{
    value++;
}

void SetByOut(out int value)
{
    value = 34;
}

Live Demo on .NET Fiddle

以下就不能編譯,因為 out 引數必須在方法返回(這將編譯使用 ref 代替)之前分配一個值:

void PrintByOut(out int value)
{
    Console.WriteLine("Hello!");
}

使用 out 關鍵字作為通用修飾符

在定義通用介面和委託時,out 關鍵字也可用於泛型型別引數。在這種情況下,out 關鍵字指定 type 引數是協變的。

協方差使你可以使用比泛型引數指定的派生型別更多的派生型別。這允許隱式轉換實現變體介面的類和委託型別的隱式轉換。引用型別支援協方差和逆變,但值型別不支援它們。 - MSDN

//if we have an interface like this
interface ICovariant<out R> { }

//and two variables like
ICovariant<Object> iobj = new Sample<Object>();
ICovariant<String> istr = new Sample<String>();

// then the following statement is valid
// without the out keyword this would have thrown error
iobj = istr; // implicit conversion occurs here