C# “实用”的示例;参考「;使用

C# “实用”的示例;参考「;使用,c#,ref,C#,Ref,我正在努力在真实的应用程序中使用“ref”(通过引用传递参数)。我想举一个简单且主要有意义的例子。通过向方法中添加返回类型,到目前为止我发现的所有内容都可以轻松地重做。 有人知道吗? 谢谢 框架中内置的TryParse方法就是典型的例子。它们使用out而不是ref,但语义相同,只是调用方不需要初始化值。例如: int result; bool isSuccess = int.TryParse("some string", out result); if (isSuccess) { //

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

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

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

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

一个可能的例子:。如果不通过引用传递变量,就无法以原子方式执行增量

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

老实说,我不能说我自己使用了
ref
太多,我通常不需要返回多个值,甚至
out
通常也足够了。我所看到的许多引用案例,都是由于作者不理解引用类型时.NET中的参数是如何传递的。

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

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


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

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

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

像这样的函数,如果没有
ref
关键字就无法完成。

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

在这里,您可以获取一个递归函数,并将其重新编写为一个方法,该方法可以在一组值上重复调用。原因是,不是深入堆栈,而是堆栈保持平坦,因为每次调用后都返回,而不是调用自己


关于GJ

是的,但我的意思是在任何实际示例中特别提到ref:)我认为它很简单,但仍然无法思考任何示例。@Loj,ref在您想要修改方法内部的值类型时很有用。我知道,但您能给我举个实际示例吗?@Loj:我一直使用
TryParse
,偶尔也会有类似的助手函数。它怎么会不切实际呢?如果
TryParse
不实用,那么这肯定不实用。事实上,如果我在一个我负责维护的应用程序中看到这样的代码,我可能会吓一跳。这似乎不是一个有意义的例子,这正是OP所要求的。我正在考虑使用course@Loj当前位置我认为不需要任何“当然”关于它-
ref
对于引用类型仍然可能有用,如果您希望调用方的参数表达式在调用后引用不同的对象。“我见过使用ref的许多情况,都是因为作者不理解引用类型时参数是如何在.NET中传递的。”非常正确的Jon!!!杰出的现在我怀疑我是否会成为一名优秀的程序员,我永远不会想到这一点。@Loj:最重要的是,我认为你应该从这个问题的答案中学到的是,你很少会用到
ref
关键字。你想不起来这一事实并不表明你是个糟糕的程序员。@Loj:是的,科迪是对的。我很少使用ref关键字。我考虑使用Swap函数,因为这只是我一直记得的ref示例(不知道为什么)我认为这是一个非常好的例子,即使对于非泛型类型,它也使交换变得优雅和简单。我会小心地交换包含字符串的自定义类,该字符串将被交换。您不需要REF,因为它已经是引用,并且只会更改引用的数据。传递字符串时,您正试图交换引用本身。这里有一个很好的参考:从某种意义上说,我不同意没有ref键盘就不能完成这个功能的假设。把你的绳子放在课堂上。
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}
}