C# 若字符串是引用类型,为什么不发生按引用传递?

C# 若字符串是引用类型,为什么不发生按引用传递?,c#,asp.net,vb.net,pass-by-reference,value-type,C#,Asp.net,Vb.net,Pass By Reference,Value Type,我读过一篇文章 因此,int是值类型,form是引用类型的一个示例 Point myPoint = new Point (0, 0); // a new value-type variable Form myForm = new Form(); // a new reference-type variable string mystringval="test"; Test (myPoint, myForm); // Test is

我读过一篇文章

因此,
int
是值类型,
form
是引用类型的一个示例

Point myPoint = new Point (0, 0);      // a new value-type variable
Form myForm = new Form();              // a new reference-type variable
string mystringval="test";
Test (myPoint, myForm);                // Test is a method defined below

void Test (Point p, Form f)
{
      p.X = 100;                       // No effect on MyPoint since p is a copy
      f.Text = "Hello, World!";        // This will change myForm’s caption since
                                       // myForm and f point to the same object
      f = null;                        // No effect on myForm
}
因此,如果我将一个字符串值传递给函数测试,它是否会改变我已经在外部声明的原始值,而不是表单变量
myform

另外,如果值将保存在堆栈中,并且只有引用将存储在堆中,那么将字符串保留为引用类型的好处是什么

如果我将一个字符串值传递给函数测试,它是否也会更改我已经在外部声明的原始值

否,
myForm
的值也没有改变,
myForm
变量仍然指向/引用相同的
Form
对象(通过
new Form()
创建的对象)

Test
方法中,调用时:

f.Text = "Hello, World!";
您没有更改变量
f
,而是更改了不同的
f.Text

换句话说,您正在更改
f
myForm
都引用的对象的属性。但是仍然
f
myForm
引用相同的原始对象

请注意,将
f
更改为
null
时,变量
myForm
没有更改。现在,
f
没有引用任何内容,但是
myForm
变量仍然引用原始对象

如果要更改原始的
myForm
变量(使其指向/引用另一个
Form
对象)或
mystringval
(使其引用另一个字符串),则通过如下引用将其传递给测试方法:

void Test (Point p, ref Form f)
{
    ...
}

void Test (Point p, ref string s)
{
    ...
}
如果我将一个字符串值传递给函数测试,它是否也会更改我已经在外部声明的原始值

否,
myForm
的值也没有改变,
myForm
变量仍然指向/引用相同的
Form
对象(通过
new Form()
创建的对象)

Test
方法中,调用时:

f.Text = "Hello, World!";
您没有更改变量
f
,而是更改了不同的
f.Text

换句话说,您正在更改
f
myForm
都引用的对象的属性。但是仍然
f
myForm
引用相同的原始对象

请注意,将
f
更改为
null
时,变量
myForm
没有更改。现在,
f
没有引用任何内容,但是
myForm
变量仍然引用原始对象

如果要更改原始的
myForm
变量(使其指向/引用另一个
Form
对象)或
mystringval
(使其引用另一个字符串),则通过如下引用将其传递给测试方法:

void Test (Point p, ref Form f)
{
    ...
}

void Test (Point p, ref string s)
{
    ...
}

@GrantWinney,如果字符串是不可变的,为什么不使用提供的最后一个值更新它?为什么要给引用类型指定ref?@GrantWinney,如果字符串是不可变的,为什么不使用提供的最后一个值更新它?我为什么要给引用类型加ref?谢谢..我理解你的意思。所以字符串被归类为引用类型,因为它可能包含堆栈无法处理的巨大数据。我说得对吗?如果是这样,字符串的值将存储在heap中?将字符串保存在堆中有什么好处?我相信这不是选择的问题。由于字符串大小的性质,它需要在堆中。毕竟在c语言中,字符串只是一个指向内存的指针,内存的结尾用a/0标记。这可能是错误的,因为我对c#.@user833985相当陌生-我认为您对堆栈和堆有一些误解。您应该忽略这一区别,因为它们存储在哪里对对象的行为并不重要。您应该关注的是这两个概念——“值与引用类型”和“可变与不可变类型”。正确。堆与堆栈是实现细节。CLR当然不会将对象的大小作为存储对象的决定因素。即使是这样,也需要确保对象的行为不会因为超过了大小阈值而改变,并最终存储在不同的数据结构中。那将导致严重的不确定性程序。谢谢你。我理解你的观点。所以字符串被归类为引用类型,因为它可能包含堆栈无法处理的巨大数据。我说得对吗?如果是这样,字符串的值将存储在heap中?将字符串保存在堆中有什么好处?我相信这不是选择的问题。由于字符串大小的性质,它需要在堆中。毕竟在c语言中,字符串只是一个指向内存的指针,内存的结尾用a/0标记。这可能是错误的,因为我对c#.@user833985相当陌生-我认为您对堆栈和堆有一些误解。您应该忽略这一区别,因为它们存储在哪里对对象的行为并不重要。您应该关注的是这两个概念——“值与引用类型”和“可变与不可变类型”。正确。堆与堆栈是实现细节。CLR当然不会将对象的大小作为存储对象的决定因素。即使是这样,也需要确保对象的行为不会因为超过了大小阈值而改变,并最终存储在不同的数据结构中。这将导致严重的不确定性程序。