C#直接传递引用类型vs out参数

时间:2012-03-26 15:50:00

标签: c#

我有两种方法:

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参数之间的区别。

4 个答案:

答案 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);'

相关问题