为什么我需要通过引用交换函数来传递字符串?

时间:2011-12-22 13:15:11

标签: c# .net string value-type reference-type

在C#中,string是引用类型。然后,

为什么我需要让我的交换函数具有ref参数?

swap(ref string first, ref string second) //swap(string first, string second) doesn't work
{
     temp = first;
     first = second
     second = temp;
}

6 个答案:

答案 0 :(得分:7)

你混淆了两种不同的引用。字符串是对实例的引用。您的交换函数引用变量

以这种方式思考。你有两本书,“圣诞颂歌”和“匹克威克论文”。他们是书;他们有页面和文字等等。

你有十张纸。五说“圣诞颂歌”。五说“匹克威克论文”。论文是参考的书籍。他们不是书。

你有十个标有A,B,C,D,E,F,G,H,I,J的抽屉。你把“A Christmas Carol”的文件放入抽屉A到E,以及那些说的文件“Pickwick Papers”进入抽屉F到J.

现在你要交换抽屉E和I的内容。你需要给交换器什么信息?你不能告诉交换器“交换引用圣诞卡罗的Pickwick论文“,因为这会改变所有十个抽屉,而不仅仅是E和I.您必须给交换器的信息是”E“和”I“。你必须传递两个变量的引用;变量本身包含对书籍的引用这一事实无关紧要。

你的交换器有三个自己的抽屉,标记为第一,第二和临时。它需要两张纸。一个人说“E”,那个标有“第一个”的抽屉里面。一个人说“我”,那个标签上写着“第二个”。

交换器在“第一个”中查找并找到一个写着“E”的文件。它看起来是“E”并找到一篇说“圣诞颂歌”的论文。它制作了那张纸的复印件并将副本放在“临时”中......你会看到这是如何从这里开始的。我希望。

答案 1 :(得分:3)

因为默认情况下C#中的参数是按值传递的,而不是参考。添加ref会为您提供传递引用行为。

答案 2 :(得分:3)

对字符串的引用按值传递。通过值传递引用和通过引用传递对象之间存在很大差异。不幸的是,在两种情况下都使用了“引用”这个词。

答案 3 :(得分:3)

是的,string是一种参考类型,而且

void swap(string first, string second)

string对象的引用传递给函数。 但string是不可变的,因此交换函数不可能通过这些引用更改对象。对于字符串,实现交换函数的唯一方法是使用ref关键字通过引用传递引用,以便可以交换引用。

OTOH,如果你有一个可变类,你可以在不使用ref关键字的情况下编写交换函数:

class Foo
{
    public int Bar { get; set; }
}

static void Swap(Foo first, Foo second)
{
    var temp = first.Bar;
    first.Bar = second.Bar;
    second.Bar = temp;
}

Foo foo1 = new Foo { Bar = 1 };
Foo foo1Copy = foo1;
Foo foo2 = new Foo { Bar = 2 };
Swap(foo1, foo2);

但是请注意,在交换之后,foo1Copy.Bar == 2,因为foo1和foo1Copy引用的对象被修改了。

答案 4 :(得分:0)

如果将对象传递给方法,则传递的是实际对象而不是对象内存中的地址。然后,您无法为其分配新值,因为您将更改哪个对象存储在其他位置的内存地址中,而不是原始对象。

通过添加ref关键字,您可以通过引用传递对象。这意味着您基本上可以让方法访问存储对象的地址,因此当您交换对象时,原始内存地址将引用交换对象。

答案 5 :(得分:0)

String是引用类型。默认情况下,它通过值传递给方法。如果您确实想要更改字符串的值,则需要通过引用传递它。下面的msdn文章详细解释了它。 http://msdn.microsoft.com/en-us/library/s6938f28(v=vs.80).aspx