1

I am trying to do a search/replace on values within a List(of String).

Dim l As New List(Of String) From {"Hello", Chr(10), "World"}

Iterate the list, and perform the search and replace:

For Each s As String In l
    s = s.Replace(Chr(10), String.Empty)
Next

However, tracing this back out, the Chr(10) has not been replaced. Chr(10) is a line break. Tracing with:

Trace.Warn(String.Join(",", l))

outputs

Hello,
,World

Attempting this slightly differently works perfectly however:

For i As Integer = 0 To l.Count - 1
    l(i) = l(i).Replace(Chr(10), String.Empty)
Next

Output:

Hello,,World

I thought that s within the For loop provided an instance to the actual string, not a copy of it? Can anyone clarify what's going on here?

EvilDr
  • 8,943
  • 14
  • 73
  • 133
  • 3
    String objects are **immutable** as they were value types. It doesn't matter where you store them...you can create a new modified one but you can't change an existing one in-place – Adriano Repetti Oct 15 '14 at 12:53
  • @AdrianoRepetti thank you very much. I went to do some research and found this very helpful explanation of strings and immutability http://stackoverflow.com/a/17942294/792888 (tagged as Java but that doesn't matter) – EvilDr Oct 15 '14 at 13:02

2 Answers2

2

In your first snippet:

For Each s As String In l
   s = s.Replace(Chr(10), String.Empty)
Next

s is a local reference to the string in the list. You are re-assigning the reference to a different string, but the list still has the original reference, pointing to the original string.

Your second loop is replacing the reference in the list with a reference to the new string, therefore you get your expected result.

Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
jlew
  • 10,491
  • 1
  • 35
  • 58
  • 1
    Because you're assigning new value to a local variable (bad habit to change foreach, anyway) but you're not updating your list. – Adriano Repetti Oct 15 '14 at 12:59
  • 1
    @AdrianoRepetti Did you actually read the answer? That's exactly what I'm explaining – jlew Oct 15 '14 at 13:00
1

Adriano Repetti is right. but depend on your further collection usage the follwing might be a use-case

Dim l = New List(Of String)() From { _
    "Hello", _
    Chr(10), _
    "World" _
}
Trace.Warn([String].Join(",", l.Select(Function(s) s.Replace(Chr(10), String.Empty))))
Yaugen Vlasau
  • 2,148
  • 1
  • 17
  • 38