vb.net - studio - vb net concatenar strings
¿Por qué no puedo proyectar ToString() en VB? (3)
Si intenta compilar la consulta siguiente en Visual Basic .NET, falla.
From x In {1, 2} Select x.ToString()
El error dado por el compilador es:
El nombre de la variable de rango no puede coincidir con el nombre de un miembro de la clase ''Objeto''.
Sin embargo, no hay nada de malo con la consulta C # equivalente:
from x in new[]{1, 2} select x.ToString()
Esto no ocurre con la sobrecarga de ToString
que toma un formato (es un miembro de Int32, no de un objeto). Sucede con otros miembros de Object, siempre que no tomen un argumento: con GetType y GetHashCode falla; con Equals (objeto) compila.
¿Por qué está establecida esta restricción y qué alternativas puedo usar?
Así es como lo entiendo. Considera el siguiente código:
Dim q = From x In {"Bob", "Larry"}
Select x.Length
Select Length * 2
En la consulta anterior, el compilador de VB automáticamente "adivina" el nombre de la variable Length
en función de la expresión x.Length
. Ahora bien, es cierto que no solicitó esto; es solo una característica que se proporciona ya sea que te guste o no. Pero ahora considera esto:
Dim q = From x In {"Bob", "Larry"}
Select (x.Length)
Select Length * 2
Lo anterior no se compila porque la expresión dentro de la primera cláusula Select
no es tan simple como en el primer caso (créalo o no); los paréntesis complican las cosas lo suficiente para que el compilador no elija el nombre Length
; en cambio, genera un nombre que no se puede utilizar desde el código.
Entonces, básicamente, lo que está sucediendo con ToString()
es que esta expresión es lo suficientemente simple para que el compilador la use para generar un nombre de variable, que podría usarse si la consulta se ampliara para hacer uso de esta variable, por ejemplo:
Dim q = From x In { 1, 2 }
Select x.ToString()
Select ToString.Length
Sin embargo, ToString
no es un nombre legal para una variable ya que es miembro de System.Object
(no podría decir por qué sería el caso de las variables dentro de las consultas LINQ pero no para las variables locales estándar).
No podría decirte exactamente por qué VB tiene esta ridiculez, pero la solución simple es poner la llamada al método en parens.
Dim q = From x In {1, 2} Select (x.ToString())
Si bien no puedo ofrecer detalles sobre el error, una solución simple es:
From x In {1, 2, 3} Let str = x.ToString() Select str
Por lo que vale, cuando tienes la siguiente línea:
Dim b = From num In {1, 2, 3} Select num.ToString("d")
es compila y descompila a (usando Reflector, a C #):
public class Class1
{
[CompilerGenerated]
private static string _Lambda$__1(int num)
{
return num.ToString("d");
}
public void Test1()
{
IEnumerable<string> b = new int[] { 1, 2, 3 }
.Select<int, string>(new Func<int, string>(Class1._Lambda$__1));
}
}
No parece haber ninguna clase anónima en el camino.