将“引用类型”作为带有'ref'关键字的参数传递给方法,这样做有意义吗?

4

可能是重复问题:
C#:什么是用于引用类型变量的“ref”?

嗨,

将“引用类型”作为带有'ref'关键字的参数传递给方法是否有意义?

还是这只是一种无意义的做法,因为它已经是一个引用类型而不是值类型?

谢谢!

7个回答

5

它允许您更改引用变量本身,以及它所指向的对象。

如果您认为您可能在方法内部使变量指向不同的对象(或null),那么这是有意义的。

否则,没有必要。


所以,如果我没有使用'ref'关键字传递参数,并将其引用更改为null,那么如果我从方法中返回对象,它不会是null,对吗? - pencilCake
@pencilCake:引用不会是null。 (对象从来不会是“null”。) - user541686
在方法的范围内,它将被视为null,但一旦离开该方法,它仍然保持原样-非null-? - pencilCake

3

如果使用它,会有所不同,因为它允许该方法更改您的变量指向的实例。

换句话说,当您想要使您的变量指向引用类型的不同实例时,使用它。

private static void WithoutRef(string s)
{
    s = "abc";
}

private static void WithRef(ref string s)
{
    s = "abc";
}

private static void Main()
{
    string s = "123";

    WithoutRef(s);
    Console.WriteLine(s); // s remains "123"

    WithRef(ref s);
    Console.WriteLine(s); // s is now "abc"
}

3

当使用ref关键字传递引用类型时,你将以引用的形式传递该引用,这是有意义的。这意味着,如果方法希望,它可以替换该引用:

public void CallRef()
{
    string value = "Hello, world";
    DoSomethingWithRef(ref value);
    // Value is now "changed".
}

public void DoSomethingWithRef(ref string value) 
{
    value = "changed";
}

0

如果你想要传入的变量指针被改变,那么就需要这样做。


1
@phoog:将引用视为指针是一个相当好的比喻。您认为在这种情况下相关的区别是什么? - Cody Gray
@Cody Gray:我在转述Eric Lippert的话。首先,指针标识一个内存地址,因此您需要固定指针的目标,以便GC不会将其移动。另外,从下面第二个链接中可以看到,指针变量是用于“操纵变量本身作为数据,而不是操纵该变量的值作为数据。”http://blogs.msdn.com/b/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx;http://blogs.msdn.com/b/ericlippert/archive/2011/03/07/references-and-pointers-part-one.aspx;http://blogs.msdn.com/b/ericlippert/archive/2011/03/10/references-and-pointers-part-two.aspx - phoog

0

在C#中,ref与VB中的ByRef是相同的,没有区别。 - user541686
我已经编辑了这段文字 - 决定它本来就很混乱 - 并包含了重复问题中的示例。 - Stuart
@Stuart:我取消了我的踩。 :) - user541686
很酷 - 值得学习 - 我想我在 VB 上误解了什么 - 我本质上是一名 C++ 程序员 :) - Stuart
不确定原始答案是什么,因为没有编辑历史记录。但是Mehrdad确实是正确的。在VB.NET中,“ByRef”等同于C#中的“ref”。在VB.NET中,“ByVal”等同于省略C#中的限定符,因为在这两种语言中,默认情况下都是按值传递。 - Cody Gray
+1 回馈给你,感谢指出重复问题。 - slugster

0

这不是胡说八道。当你这样做时,你是通过引用传递引用。

例如:

class X
{
     string y;
     void AssignString(ref string s)
    {
        s = "something";
    }
    void Z()
    {
        AssignString(ref this.y};
    }
}

-1
考虑以下代码。您认为这个程序的输出会是什么?
string s = "hello world";
Console.WriteLine(s);

foo(s);
Console.WriteLine(s);

bar(ref s);
Console.WriteLine(s);

void foo(string x)
{
    x = "foo";
}

void bar(ref string x)
{
    x = "bar";
}

输出结果为:

hello world
hello world
bar

当调用方法bar时,你通过引用(而不是值)传递了字符串s的引用,这意味着s将在调用站点发生更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接