C# 将字符串作为参数传递:它是复制的还是引用的?我很困惑

C# 将字符串作为参数传递:它是复制的还是引用的?我很困惑,c#,C#,我一直在阅读关于值和引用类型以及ref关键字的文章,特别关注这篇文章:。Jon Skeet的答案字符串的引用是通过值传递的。按值传递引用和按引用传递对象之间有很大区别。不幸的是,在这两种情况下都使用了reference这个词。即使在他的例子之后,我也感到困惑 考虑这一点: string x = "foo"; void Bar(string s) { Console.Write(s); } Bar(x); 我的问题是:当将x传递给Bar时,s是表示内存中x的完整副本还是指向x的指针?

我一直在阅读关于值和引用类型以及ref关键字的文章,特别关注这篇文章:。Jon Skeet的答案字符串的引用是通过值传递的。按值传递引用和按引用传递对象之间有很大区别。不幸的是,在这两种情况下都使用了reference这个词。即使在他的例子之后,我也感到困惑

考虑这一点:

string x = "foo";

void Bar(string s)
{
    Console.Write(s);
}

Bar(x);

我的问题是:当将x传递给Bar时,s是表示内存中x的完整副本还是指向x的指针?如果x真的很大,这就变得很重要了。当我只想将s转换成不同的东西而不改变s本身时,通过ref传递x是否会对性能有好处?

c中的所有字符串都是不可变的,因此传递指针是安全的。在您的示例中,foo是一个静态常量,它将存在于程序集中的某个位置,并加载到内存中的一个固定位置。您正在声明x并分配该位置。然后将该指针传递到Bar,其中新的局部变量s也被赋值

如果Bar更改了s的值,则不会更改x的当前值,因为这两个变量都是指针位置的副本

如果将Bar更改为将s作为参考参数,则s不再是单独的局部变量。相反,x本身的位置将被传递到Bar中,对s和x的任何更改都将更改同一指针。变量s成为指向字符串的变量的引用

将x传递给条形图时,s是否表示x的完整副本 在内存中,还是s是指向x的指针

x和s都是引用内存中相同字符串对象的变量-Foo

在以下情况下,通过ref传递x是否有性能优势 我想做的就是把s转换成不一样的东西 改变自己

通过使用ref关键字传递s参数,可以将x变量分配给内存中的其他字符串对象,也可以通过将新字符串或null分配给s参数来将其分配给null。但是没有性能差异,因为在这两种情况下,仅复制一个地址,即分别复制字符串Foo的地址或变量x的地址-不复制字符串Foo的内容

“将x传递给条时,s是表示内存中x的完整副本还是s是指向x的指针”

x是对“foo”的引用,而不是“foo”的完整副本

当你这样做的时候

巴克斯

x是通过值传递的,也就是说,传递的是x的副本,而不是x本身,所以您在Bar中所做的任何操作都不会改变x所指的内容。如果您想让Bar更改x引用的内容,则必须使用ref关键字通过引用传递它。这需要更改律师协会的签名,如下所示:

void Barref字符串s{}

然后,您可以将其称为:

巴雷夫x

在这种情况下,通过引用传递与

绩效效益


而是关于实现所期望的,即改变x所指的内容。

传递的是x参考的副本。顺便说一句,转换字符串总是会产生新字符串。您编写的代码在任何时候都不会创建字符串的多个副本。您不需要通过ref传递它。s也不是指向x的指针。x是对foo的引用。s是该引用的副本,指向同一个foo.Tx作为反馈。那么它是否类似于C中的**指针?我想说它只是类似于*指针。字符串唯一的特殊之处是它是不可变的,类只是不公开任何变异API。传递字符串就像传递任何其他类对象一样。如果您将字典传递给函数,则不会期望生成副本。你基本上是在传递一个指针的副本。我从中得到的是,我们这里讲的是指针,而不是传递的值的副本,对吗?类类型总是在堆上分配的。类变量始终是指针。值类型存储在它们出现的范围内,堆栈上的局部变量,它们包含的类中的类字段。谢谢,正如其他人指出的,它指向一个地址,这就是我想知道的。让我困惑的是你的“传递的是x的副本,而不是x本身”。这意味着一个副本,不是其他人“指出”的指针。它是引用的副本,即正在传递的x的副本,而不是“foo”的副本。x与“foo”不同,它指向“foo”,我不喜欢在这里使用单词指针,因为它有来自C/C的行李++