2012-03-26 47 views
8

我有两种方法:C#传引用类型VS out参数

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); 

一般来说,我想了解通过引用类型之间的区别,或者作为输出参数。

回答

6

在你的榜样,方法B将无法​​编译,因为out参数被认为是未初始化的,所以你必须初始化它,然后才能使用它。此外,调用方法与out参数时,需要指定在调用点的out关键字:

B(out numsB); 

而且你不需要调用之前初始化numbsB变量,因为它会被覆盖通过该方法。

乔恩斯基特有一个伟大的文章,解释了各种方式来传递参数:Parameter passing in C#

0

版本B的,功能有变量直接访问。它就像'ref'关键字一样,除了变量必须从获取参数的函数中分配。它可以让你从一个函数返回多个值。调用语法是'B(out numsB);'

3

非参考非输出参数(如局部变量)表示存储位置。如果存储位置的类型是引用类型,则存储位置将持有对该类型实例的引用。

Ref和输出参数,相反,保持的存储位置的参考。该存储位置可以是局部变量,字段或数组元素。换句话说,ref和out参数引入了另一个间接层。如果在方法中有引用类型的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参数相当少见,甚至更少见于参考类型。

请注意,ref参数必须由调用方初始化,而out参数必须由被调用方初始化。如果您从不为ref参数赋值,那么它可能应该是一个“正常”参数。如果您从不向out参数赋值(如您的示例中所示),那么您的代码将无法编译。