Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

141
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda