交换vs ref

时间:2013-11-24 01:00:51

标签: c# swap

实现交换功能的更好方法是什么?如何使用ref比使用ref更好,反之亦然?使用其中一种或其他方面会产生的任何其他好处或缺点?

swapref(ref T a, ref T b) {
  T temp = a;
  a = b;
  b = temp;
}

swapout(out T a, out T b)
{ 
   T temp = a;
   a = b;
   b = temp;
}

3 个答案:

答案 0 :(得分:8)

根据定义,Swap()函数要求传递的参数具有值。因此,您应该使用ref

使用out意味着可以传递(并允许)未初始化的参数(实际上不应该编译,因为你将使用未分配的参数)

答案 1 :(得分:1)

如果我将swapout方法修改为更接近于编译的内容......

static void swapout<T>(out T a, out T b)
{
    T temp = a; // ERROR: Use of unassigned out parameter 'a'
    a = b;      // ERROR: Use of unassigned out parameter 'b'
    b = temp;
}

...它仍会产生您在评论中看到的错误。

当使用out修改参数时,它被视为未初始化,并且方法的责任是为其分配一个确定的值。交换方法的重点是对传递给它的值进行操作,但是使用out时,这些参数的值是不受限制的,因为调用者不需要传递初始化变量。因此,要回答您的问题,不仅要使用ref优质解决方案,而且使用out根本不是一个可行的解决方案。

答案 2 :(得分:1)

在C#中,明确赋值是一个大问题,它可以确保您的代码在使用之前为变量赋值,从而避免麻烦。语言区分 ref out 的核心原因。其他语言没有这种区别,它们只有“按值传递”与“按引用传递”的语法。在VB.NET中,ByVal vs ByRef就是例如。通过使用 out 而不是 ref ,您可以清楚地说明数据流并承诺在调用之前不必分配变量,并且之后被分配。编译器会验证这一点并在您违反该规则时提出抱怨。

您不能做的是交换“未分配”状态。没有语法允许您表示操作后变量分配。因此,必须使用 ref 。 Nullable为您提供选项,而不是范围。