Passing ByVal string to VB.NET And C #

So are strings reference types? My understanding is a reference to a string on the heap that is passed even when you pass the ByVal string to the method.

Soooo .....

String myTestValue = "NotModified"; TestMethod(myTestValue); System.Diagnostics.Debug.Write(myTestValue); /* myTestValue = "NotModified" WTF? */ private void TestMethod(String Value) { Value = "test1"; } 

As an alternative

 Dim myTestValue As String = "NotModified" TestMethod(myTestValue) Debug.Print(myTestValue) /* myTestValue = "NotModified" WTF? */ Private Sub TestMethod(ByVal Value As String) Value = "test1" End Sub 

What am I missing? And what happens under the hood? I would set my life that meaning would change.

+6
c # reference-type
source share
5 answers

Reference types are passed by value-by-value reference in .NET. This means that assigning a different value to the actual parameter does not actually change the original value (unless you use ByRef / ref). However, everything you do to change the actual object to be transferred will change the object referenced by the invocation method. For example, consider the following program:

 void Main() { var a = new A{I=1}; Console.WriteLine(aI); DoSomething(a); Console.WriteLine(aI); DoSomethingElse(a); Console.WriteLine(aI); } public void DoSomething(A a) { a = new A{I=2}; } public void DoSomethingElse(A a) { aI = 2; } public class A { public int I; } 

Output:

 1 1 2 

The DoSomething method assigned its parameter a to a different value, but this parameter is only a local pointer to the location of the original a from the calling method. Changing the value of a pointer did not change the value of the calling method a . However, DoSomethingElse did make a change to one of the values โ€‹โ€‹of the link object.

No matter what the other responders say, string not so exceptional. All objects behave in this way.

Where string differs from many objects in that it is immutable: there are no methods or properties or fields in the string that you can call to actually modify the string. Once a string is created in .NET, it is read-only.

When you do something like this:

 var s = "hello"; s += " world"; 

... the compiler turns this into something like this:

 // 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(); 

This last line generates a new line, but S1 and S2 are still hanging around. If they are constant lines embedded in the assembly, they will remain there. If they were created dynamically and no longer have references to them, the garbage collector can delete links to free memory. But the key is to understand that S1 has never changed. The variable pointing to it just changed to point to another line.

+7
source share

Everything is passed by value, unless you specify otherwise. When you pass a String, you actually pass the reference by value.

For strings, this does not really matter, since strings are immutable. This means that you can never change the line you get. However, for other classes, you can change the object passed by value (if, like String, it cannot be changed). What you cannot do and what is passed by reference allows you to change the variable that you pass.

Example:

 Public Class Example Private Shared Sub ExampleByValue(ByVal arg as String) arg = "ByVal args can be modifiable, but can't be replaced." End Sub Private Shared Sub ExampleByRef(ByRef arg as String) arg = "ByRef args can be set to a whole other object, if you want." End Sub Public Shared Sub Main() Dim s as String = "" ExampleByValue(s) Console.WriteLine(s) ''// This will print an empty line ExampleByRef(s) Console.WriteLine(s) ''// This will print our lesson for today End Sub End Class 

Now this should be used very sparingly, because the default value is the default value and is expected. In particular, in VB, which does not always make it clear when you follow a link, this can cause a lot of problems when some method unexpectedly starts your variables.

+3
source share

All types, including reference types, are passed by default, as in your example, which means that a copy is passed that link. That way, regardless of whether rewriting an object in this way will have any effect when you pass it by value. You just change what the copy refers to. You must explicitly pass the link in order to achieve what you are trying to do.

Only if you change an object that has passed by value, the effect can be seen outside the method. Of course, strings are immutable, so this is not applicable here.

+2
source share

You are transmitting a copy, not the actual link.

read this article from Microsoft

http://msdn.microsoft.com/en-us/library/s6938f28.aspx

0
source share
  • When you pass a string to a method, a copy of the link is taken. Thus, Value is a whole new variable that just relates to the same line in memory.
  • The string literal "test" also created as an object of a real reference type. This is not just a value in the source code.
  • When you assign "test" to Value , the link for your Value variable is updated to refer to "test" instead of the original string. Since this link is just a copy (as we saw in step 1), the variable myTestValue outside the function remains unchanged and still refers to the original string.

You can better understand this by testing by type with a property that you can update. If you make changes only to the property, this change is visible outside the function. If you try to replace the entire object (as you do with this line), this is not visible outside the function.

0
source share

All Articles