退出

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