static class outRefTest{
public static int myfunc(int x){x=0; return x; }
public static void myfuncOut(out int x){x=0;}
public static void myfuncRef(ref int x){x=0;}
public static void myfuncRefEmpty(ref int x){}
// Define other methods and classes here
}
int x;
Foo(ref x); // error: x is uninitialized
void Bar(out int x) {} // error: x was not written to
例如,int.TryParse返回bool并接受out int参数:
int value;
if (int.TryParse(numericString, out value))
{
/* numericString was parsed into value, now do stuff */
}
else
{
/* numericString couldn't be parsed */
}
if (int.TryParse(numericString, out int value))
{
// 'value' exists and was declared in the `if` statement
}
else
{
// conversion didn't work, 'value' doesn't exist here
}
out关键字使参数通过引用传递。这类似于ref关键字,除了ref要求在传递变量之前对其进行初始化。要使用out形参,方法定义和调用方法都必须显式使用out关键字。例如:
c# < / p >
class OutExample
{
static void Method(out int i)
{
i = 44;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}
虽然作为out参数传递的变量在传递之前不必初始化,但被调用的方法需要在方法返回之前赋值。
虽然ref和out关键字导致不同的运行时行为,但它们在编译时不被认为是方法签名的一部分。因此,如果唯一的区别是一个方法接受ref参数,另一个方法接受out参数,则方法不能重载。例如,下面的代码将无法编译:
c# < / p >
class CS0663_Example
{
// Compiler error CS0663: "Cannot define overloaded
// methods that differ only on ref and out".
public void SampleMethod(out int i) { }
public void SampleMethod(ref int i) { }
}
但是,如果一个方法使用ref或out参数,而另一个方法两者都不使用,则可以进行重载,如下所示:
c# < / p >
class OutOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(out int i) { i = 5; }
}
属性不是变量,因此不能作为out参数传递。
有关传递数组的信息,请参见使用ref和out传递数组(c#编程指南)。
以下类型的方法不能使用ref和out关键字:
Async methods, which you define by using the async modifier.
Iterator methods, which include a yield return or yield break statement.
例子
当你想要一个方法返回多个值时,声明一个out方法是有用的。下面的例子使用out用一个方法调用返回三个变量。注意,第三个参数被赋值为null。这使得方法可以有选择地返回值。
c# < / p >
class OutReturnExample
{
static void Method(out int i, out string s1, out string s2)
{
i = 44;
s1 = "I've been returned";
s2 = null;
}
static void Main()
{
int value;
string str1, str2;
Method(out value, out str1, out str2);
// value is now 44
// str1 is now "I've been returned"
// str2 is (still) null;
}
}