我有两种方法:
public void A(List<int> nums)
{
nums.Add(10);
}
public void B(out List<int> nums)
{
nums.Add(10);
}
这两个电话之间有什么区别?
List<int> numsA = new List<int>();
A(numsA);
List<int> numsB = new List<int>();
B(out numsB);
一般来说,我试图理解传递引用类型as-is或out参数之间的区别。
答案 0 :(得分:7)
在您的示例中,方法B
将无法编译,因为out
参数被视为未初始化,因此您必须先将其初始化,然后才能使用它。此外,在使用out
参数调用方法时,您需要在呼叫站点指定out
关键字:
B(out numsB);
并且您不需要在调用之前初始化numbsB
变量,因为它将被方法覆盖。
Jon Skeet有一篇很棒的文章解释了传递参数的各种方法:Parameter passing in C#
答案 1 :(得分:3)
非ref,非out参数,如局部变量,表示存储位置。如果存储位置的类型是引用类型,则存储位置包含对该类型实例的引用。
相反,参考和输出参数保持对存储位置的引用。该存储位置可以是局部变量,字段或数组元素。换句话说,ref和out参数引入了另一层间接。如果方法中有reference-type ref或out参数,则它表示对对象引用的引用。
为什么要引用对象的引用?如果您需要修改对象的引用(而不是修改对象本身)。
在某些狭隘的情况下,这是一种有用的技术。例如,您可能希望编写一个命令两个队列的函数,具体取决于哪个队列的值较小:
void OrderQueues(ref Queue<int> a, ref Queue<int> b)
{
if (a.Peek <= b.Peek) return;
var temp = a;
a = b;
b = temp;
}
如果要从方法返回多个值,则输出参数非常有用:
void OldestAndYoungest(IEnumerable<Person> people, out Person youngest, out Person oldest)
{
youngest = null;
oldest = null;
foreach (var person in people)
{
if (youngest == null || person.Age < youngest.Age)
youngest = person;
if (oldest == null || oldest.Age < person.Age)
oldest = person;
}
}
根据我的经验,ref和out参数相当罕见,参考类型甚至更少。
请注意,参数必须由调用者初始化,而out参数必须由被调用者初始化。如果您从未为ref参数赋值,则它应该是“正常”参数。如果您从未为out参数赋值,如示例所示,则代码将无法编译。
答案 2 :(得分:0)
out关键字导致参数通过引用传递。这是 类似于ref关键字,除了ref要求变量 在被传递之前被初始化。要使用out参数,请同时使用 方法定义和调用方法必须明确使用out 关键词。例如:
http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx
答案 3 :(得分:0)
在版本B中,该函数可以直接访问变量。它就像'ref'关键字,除了必须从参数中的函数内分配变量。它允许您从函数返回多个值。调用语法是'B(out numsB);'