11

我正在努力如何在实际应用程序中使用“ref”(通过引用传递参数)。我想有一个简单且主要有意义的例子。到目前为止,我发现的所有内容都可以通过在方法中添加返回类型来轻松重做。有人知道吗?谢谢!

4

6 回答 6

21

我想到的最好的例子是交换两个变量值的函数:

static void Swap<T>(ref T el1, ref T el2)
{
    var mem = el1;
    el1 = el2;
    el2 = mem;
}

用法:

static void Main(string[] args)
{
    string a = "Hello";
    string b = "Hi";

    Swap(ref a, ref b);
    // now a = "Hi" b = "Hello"

    // it works also with array values:
    int[] arr = new[] { 1, 2, 3 };
    Swap(ref arr[0], ref arr[2]);
    // now arr = {3,2,1}
}

ref像这样的功能,没有关键字就无法完成。

于 2011-01-10T11:17:10.220 回答
5

一个可能的极端案例:Interlocked.Increment. 如果不通过引用传递变量,就无法原子地执行增量。

老实说,我不能说我自己已经使用ref了很多 - 我通常会避开返回多个值的需要,即使这样out通常足够了。我看到 ref的许多使用案例都是由于作者不了解在引用类型方面如何在 .NET 中传递参数。

于 2011-01-10T11:14:23.550 回答
4

TryParse框架中内置的方法是典型的例子。他们使用out而不是ref但它是相同的语义,只是调用者不需要初始化值。例子:

int result;
bool isSuccess = int.TryParse("some string", out result);
if (isSuccess)
{
    // use the result here
}

如您所见,该函数返回一个布尔值,指示操作是否成功,但实际结果作为out参数返回。

于 2011-01-10T11:10:08.287 回答
1
public static void Main(string args[])
{
    int i=0;
    AddSomething(ref i);
    AddSomething(ref i);
    AddSomething(ref i);
    AddSomething(ref i);


    string mystr = "Hello";
    AddSomeText(ref mystr);
    Console.WriteLine(mystr);


    Console.WriteLine("i = {0}", i);
}


public static void AddSomeText(ref string str)
{
    str+= " World!";
}


public static void AddSomething(ref int ii)
{
    ii+=1;
}
于 2011-01-10T11:11:33.653 回答
0

我看到的最常见的地方之一是在某些框架的 Save 方法中。

原因是在许多情况下,如果对象被序列化到另一台机器然后作为新实例返回(可能带有一些额外的默认值),实际上不可能通过保存调用维护相同的对象。在这种情况下,您需要 ref 来表明原始参考不再有效。

至于它的必要性,我想不出一个需要它的例子。大多数地方都很好。

于 2011-01-10T11:14:43.337 回答
0

我认为一个很好的例子是蹦床。

这是您采用递归函数并将其重新加工为在一组值上重复调用的方法的地方。原因是堆栈没有非常深入地进入堆栈,而是保持平坦,因为您在每次调用后都返回而不是调用自己。

问候 GJ

于 2011-01-10T11:23:10.753 回答