Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

135
Vistas
IEnumerable.Select repite el parámetro de entrada en una llamada de función

Me topé con un comportamiento que no esperaba y del que no puedo encontrar la documentación. Tengo una función con 2 parámetros, uno de ellos tiene un valor predeterminado. Cuando se llama a la función dentro de un Select, por alguna razón toma el valor al que se llama y lo aplica para ambos parámetros. Ejemplo:

Tener la función:

 private static Directions PrintDir(Directions dir, int distance = 1) { Console.WriteLine($"Direction {dir}, distance {distance}"); return dir; }

Si se llama por sí solo, se comporta como se esperaba:

 using System; using System.Linq; public class Program { enum Directions { Left, Up, Right, Down }; public static void Main() { PrintDir(Directions.Left); PrintDir(Directions.Up); PrintDir(Directions.Right); PrintDir(Directions.Down); } }

huellas dactilares:

 Direction Left, distance 1 Direction Up, distance 1 Direction Right, distance 1 Direction Down, distance 1

sin embargo, cuando se llama dentro de la expresión LINQ:

 using System; using System.Linq; public class Program { enum Directions { Left, Up, Right, Down }; public static void Main() { var dirs = Enum.GetValues(typeof(Directions)) .Cast<Directions>() .Select(PrintDir) .ToList(); } }

Yo obtengo:

 Direction Left, distance 0 Direction Up, distance 1 Direction Right, distance 2 Direction Down, distance 3

Entonces, parece que el valor de Indicaciones se aplicó correctamente como el parámetro dir , pero también se convirtió a int y se aplicó en lugar del valor predeterminado como el segundo parámetro de distance .

¿Por qué pasó esto? ¿Cuáles son las reglas para las funciones dentro de Seleccionar?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Hay una sobrecarga de Select que también contiene el índice. Si usó lambdas, su código se vería así:

 Select((item,index) => PrintDir(item, index))

Si quieres evitarlo, llama a tu Select así:

 Select(item => PrintDir(item))
over 4 years ago · Santiago Trujillo Denunciar

0

Para agregar un poco más a la respuesta de SomeBody: si escribe PrintDir(Directions.Left) , el compilador compila el código PrintDir(Directions.Left, 1) -- toma el valor predeterminado y lo inserta en la llamada al método por usted.

Ahora, si intenta crear un delegado directamente desde el método, por ejemplo:

 var f = new Func<Directions, Directions>(PrintDir)

no hay ningún lugar para que el compilador inserte este valor predeterminado, por lo que no se compilará. El único tipo de delegado al que puede asignar el método directamente es uno que toma todos los parámetros, por ejemplo, Func<Directions, int, Directions> .

Sin embargo, si escribes:

 var f = new Func<Directions, Directions>(x => PrintDir(x))

El compilador puede convertir esto en:

 var f = new Func<Directions, Directions>(x => PrintDir(x, 1))

Cuando escribes:

 .Select(PrintDir)

en realidad estás escribiendo abreviatura para:

 .Select(new SomeDelegateType(PrintDir))

donde SomeDelegateType es un tipo de delegado adecuado. El compilador busca en todas las sobrecargas de Select buscando una que acepte un tipo de delegado que compilará.

Hay una sobrecarga de Select que acepta Func<Direction, Direction> , por lo que intenta esto:

 .Select(new Func<Direction, Direction>(PrintDir))

... pero eso no compila, por lo que intenta la sobrecarga que toma el índice int :

 .Select(new Func<Direction, int, Direction>(PrintDir))

y eso compila, por lo que el compilador lo elige.

(De hecho, las cosas son un poco más complejas, ya que el compilador infiere el tipo de retorno (supuse que es la Direction anterior), y también intenta encontrar la mejor coincidencia, pero esa es la esencia).

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda