在VB.NET和C#中传递字符串ByVal

Max*_*ich 6 c# vb.net reference-type byref byval

所以字符串是引用类型对吗?我的理解是,即使将字符串ByVal传递给方法,也会传递对堆中字符串的引用.

SOOO .....

String myTestValue = "NotModified";
TestMethod(myTestValue);
System.Diagnostics.Debug.Write(myTestValue); /* myTestValue = "NotModified" WTF? */

private void TestMethod(String Value)
{
    Value = "test1";
}
Run Code Online (Sandbox Code Playgroud)

另外

Dim myTestValue As String = "NotModified"
TestMethod(myTestValue)
Debug.Print(myTestValue) /* myTestValue = "NotModified" WTF? */

Private Sub TestMethod(ByVal Value As String)
    Value = "test1"
End Sub
Run Code Online (Sandbox Code Playgroud)

我错过了什么?引擎盖下发生了什么?我会打赌我的生活价值会发生变化......

Str*_*ior 7

引用类型在.NET中传递"按值引用".这意味着为实际参数指定不同的值实际上不会更改原始值(除非您使用ByRef/ref).但是,您更改传入的实际对象所做的任何操作都将更改调用方法引用的对象.例如,请考虑以下程序:

void Main()
{
    var a = new A{I=1};
    Console.WriteLine(a.I);
    DoSomething(a);
    Console.WriteLine(a.I);
    DoSomethingElse(a);
    Console.WriteLine(a.I);
}

public void DoSomething(A a)
{
    a = new A{I=2};
}

public void DoSomethingElse(A a)
{
    a.I = 2;
}

public class A
{
    public int I;
}
Run Code Online (Sandbox Code Playgroud)

输出:

1
1
2
Run Code Online (Sandbox Code Playgroud)

DoSomething方法将其a参数指定为具有不同的值,但该参数只是指向a调用方法中原始位置的本地指针.更改指针的值不会改变调用方法的a值.但是,DoSomethingElse实际上对引用对象上的某个值进行了更改.

无论其他回答者说什么,string这种方式都不例外.所有对象都以这种方式运行.

string许多对象不同的是,这是不可改变的:有没有任何上,你可以打电话真正改变串串方法或属性或字段.一旦在.NET中创建了一个字符串,它就是只读的.

当你做这样的事情:

var s = "hello";
s += " world";
Run Code Online (Sandbox Code Playgroud)

...编译器把它变成这样的东西:

// this is compiled into the assembly, and doesn't need to be set at runtime.
const string S1 = "hello"; 
const string S2 = " world"; // likewise
string s = S1;
s = new StringBuilder().Append(s).Append(S2).ToString();
Run Code Online (Sandbox Code Playgroud)

最后一行生成一个新字符串,但S1和S2仍然悬空.如果它们是装配中内置的恒定字符串,它们将保留在那里.如果它们是动态创建的并且没有对它们的更多引用,则垃圾收集器可以取消引用它们以释放内存.但关键是要意识到S1从未真正改变过.指向它的变量只是改为指向不同的字符串.