Muchos de los que ahora programamos en VB.NET venimos del viejo mundo del VB6, ese mundo de caos donde no existía la orientación a objetos y para muchas cosas tenias que tirar de la API de Windows.
Ahora que utilizamos VB.NET nuestro mundo se ha simplificado mucho pero tenemos que ir con cuidado ¡sin darnos cuenta vamos y volvemos al lado oscuro! Ya que dentro del framework existe la librería Microsoft.VisualBasic.dll que es un vínculo que nos han dejado los desarrolladores de Microsoft para que la transición fuera menos traumática.
El problema es que ese vínculo que nos dejaron con el pasado afecta directamente contra el rendimiento de nuestras aplicaciones. Un ejemplo claro de sería la función Replace.
Dim str As String = "ABA"
str = Replace(str, "A", "X")
Cuando utilizamos la función Replace, estamos llamando la función que hay en la librería Microsoft.VisualBasic, denominada Strings.Replace.
Si decompilamos esta función, con .NET Reflector, vemos que realmente se llama a la siguiente función:
1: Public Shared Function Replace(ByVal Expression As String, ByVal Find As String, ByVal Replacement As String, ByVal Optional Start As Integer = 1, ByVal Optional Count As Integer = -1, <OptionCompare> ByVal Optional [Compare] As CompareMethod = 0) As String
2: Dim str As String
3: Try
4: If (Count < -1) Then
5: Throw New ArgumentException(Utils.GetResourceString("Argument_GEMinusOne1", New String() { "Count" }))
6: End If
7: If (Start <= 0) Then
8: Throw New ArgumentException(Utils.GetResourceString("Argument_GTZero1", New String() { "Start" }))
9: End If
10: If ((Expression Is Nothing) OrElse (Start > Expression.Length)) Then
11: Return Nothing
12: End If
13: If (Start <> 1) Then
14: Expression = Expression.Substring((Start - 1))
15: End If
16: If (Find Is Nothing) Then
17: Return Expression
18: End If
19: If ((Find.Length = 0) OrElse (Count = 0)) Then
20: Return Expression
21: End If
22: If (Count = -1) Then
23: Count = Expression.Length
24: End If
25: str = Strings.ReplaceInternal(Expression, Find, Replacement, Count, [Compare])
26: Catch exception As Exception
27: Throw exception
28: End Try
29: Return str
30: End Function
Esta a su vez llama a :
1: Private Shared Function ReplaceInternal(ByVal Expression As String, ByVal Find As String, ByVal Replacement As String, ByVal Count As Integer, ByVal [Compare] As CompareMethod) As String
2: Dim ordinal As CompareOptions
3: Dim compareInfo As CompareInfo
4: Dim num5 As Integer
5: Dim length As Integer = Expression.Length
6: Dim num2 As Integer = Find.Length
7: Dim builder As New StringBuilder(length)
8: If ([Compare] = CompareMethod.Text) Then
9: compareInfo = Utils.GetCultureInfo.CompareInfo
10: ordinal = (CompareOptions.IgnoreWidth Or (CompareOptions.IgnoreKanaType Or CompareOptions.IgnoreCase))
11: Else
12: compareInfo = Strings.m_InvariantCompareInfo
13: ordinal = CompareOptions.Ordinal
14: End If
15: Do While (num5 < length)
16: Dim num4 As Integer
17: If (num4 = Count) Then
18: builder.Append(Expression.Substring(num5))
19: Exit Do
20: End If
21: Dim num3 As Integer = compareInfo.IndexOf(Expression, Find, num5, ordinal)
22: If (num3 < 0) Then
23: builder.Append(Expression.Substring(num5))
24: Exit Do
25: End If
26: builder.Append(Expression.Substring(num5, (num3 - num5)))
27: builder.Append(Replacement)
28: num4 += 1
29: num5 = (num3 + num2)
30: Loop
31: Return builder.ToString
32: End Function
Conclusión:
Cuando hacemos un Replace realmente estamos creando un StringBuilder y ejecutando un bucle While. Increible, ¿no?
Solución:
Normalmente cuando utilizamos esta función es para realizar un reemplazo de todas la coincidencia y no utilizamos la mayoría de opciones de ofrece la función Replace. Yo me simplifico la vida y utilizo la que viene nativa con el tipo String.
1: Dim str As String = "ABA"
2: str = str.Replace("A", "X")
That's it!