• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

448
Views
System.IO.Directory.Exists falla dentro de la instrucción LINQ, pero no en un bucle foreach

.NET Framework 4.7.2

Ese fue un tema muy sorprendente...

Tengo esta rutina para obtener todas las plantillas de Inventor disponibles del disco local, sin importar la versión que sea:

 private static IEnumerable<string> GetInventorTemplates_FAILS() { var publicPath = Environment.GetEnvironmentVariable("PUBLIC"); var autodeskPath = Path.Combine(publicPath, "Documents", "Autodesk"); var inventorPaths = Directory.GetDirectories(autodeskPath, "*Inventor*"); var templatePaths = inventorPaths.Select(path => Path.Combine(path, "Templates")); var templates = templatePaths.Where(Directory.Exists).SelectMany(path => Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)); // throws error ^^^^^^^^^^^^^^^^ return templates; }

Si ejecuto este código, obtengo este error:

 System.Linq.SystemCore_EnumerableDebugView`1[System.String].get_Items() calls into native method Microsoft.Win32.Win32Native.GetFullPathName(char*, int, char*, System.IntPtr). Evaluation of native methods in this context is not supported.

Lo que lo vuelve más loco es si reescribo el código, para llamar manualmente a Directory.Exists y funciona.

 private static IEnumerable<string> GetInventorTemplates_WORKS() { var publicPath = Environment.GetEnvironmentVariable("PUBLIC"); var autodeskPath = Path.Combine(publicPath, "Documents", "Autodesk"); var inventorPaths = Directory.GetDirectories(autodeskPath, "*Inventor*"); var templatePaths = inventorPaths.Select(path => Path.Combine(path, "Templates")); foreach (var path in templatePaths) if (Directory.Exists(path)) // <- no exception!!! foreach (var template in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)) yield return template; }

Obtendrá el mismo resultado si solo verifica a través de QuickWatch :

templatePaths.Where(Directory.Exists) a través del cuadro de diálogo QuickWatch

Directory.Exists (templatePaths.First()) a través del cuadro de diálogo QuickWatch

Por ahora puedo usar la versión reescrita, pero tenía mucha curiosidad si soy el afortunado... :-)

about 3 years ago · Santiago Trujillo
1 answers
Answer question

0

Eso no es un problema de .NET. El código funcionará bien, no tienes que cambiar nada. El depurador dice que no puede ejecutar la consulta de forma segura en la ventana de observación, por lo que no puede mostrar ningún resultado. El error explica que

No se admite la evaluación de métodos nativos en este contexto.

template no es una lista de documentos, es una consulta que aún no se ha ejecutado. El depurador tendría que ejecutar esa consulta para recuperar y los resultados.

Esto no es un problema ni poco común. Hay varios casos en los que el depurador no puede ejecutar una consulta LINQ o enumerar un IEnumerable de forma segura y mostrar los resultados. Si desea inspeccionar los resultados, ejecute la consulta explícitamente, por ejemplo, con ToList .

PD

Probablemente sea una buena idea usar una biblioteca global como Glob (descargas de 3M NuGet) para reemplazar todo este código con:

 var root = new DirectoryInfo(autodeskPath); var templates = root.GlobFileSystemInfos("*Inventor*/Templates/**/*.*");

.NET Core en sí mismo usa archivos globbing a través del paquete Microsoft.Extensions.FileSystemGlobbing .

 Matcher matcher = new(); matcher.AddIncludePatterns(new[] { "*Inventor*/Templates/**/*.*" }); foreach (string file in matcher.GetResultsInFullPath(autodeskPath)) { Console.WriteLine(file); }
about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error