2008-10-18 14 views
5

Quizás esté siendo un poco flojo al preguntar esto aquí, pero recién estoy comenzando con LINQ y tengo una función que estoy seguro puede convertirse en dos consultas LINQ (o una consulta anidada) en lugar de un LINQ y un par de declaraciones de foreach. ¿Algún gurú de LINQ se preocupa de refactorizar este para mí como ejemplo?¿Cómo puedo combinar este código en una o dos consultas LINQ?

La función misma recorre una lista de archivos Csproj y saca los caminos de todos los archivos .cs incluidas en el proyecto:

static IEnumerable<string> FindFiles(IEnumerable<string> projectPaths) 
{    
    string xmlNamespace = "{http://schemas.microsoft.com/developer/msbuild/2003}"; 
    foreach (string projectPath in projectPaths) 
    { 
     XDocument projectXml = XDocument.Load(projectPath); 
     string projectDir = Path.GetDirectoryName(projectPath); 

     var csharpFiles = from c in projectXml.Descendants(xmlNamespace + "Compile") 
           where c.Attribute("Include").Value.EndsWith(".cs") 
           select Path.Combine(projectDir, c.Attribute("Include").Value); 
     foreach (string s in csharpFiles) 
     { 
      yield return s; 
     } 
    } 
} 

Respuesta

8

¿Qué tal:

 const string xmlNamespace = "{http://schemas.microsoft.com/developer/msbuild/2003}"; 

     return from projectPath in projectPaths 
       let xml = XDocument.Load(projectPath) 
       let dir = Path.GetDirectoryName(projectPath) 
       from c in xml.Descendants(xmlNamespace + "Compile") 
       where c.Attribute("Include").Value.EndsWith(".cs") 
       select Path.Combine(dir, c.Attribute("Include").Value); 
+0

brillante. ¡Sabía que StackOverflow me encontraría la respuesta más rápido de lo que podría encontrarlo leyendo un libro de LINQ! muchas gracias. –

+0

No hay problema; como optimización menor, puede "dejar inc = c.Attribute (" Include "). Value", y luego donde inc.EndsWith (..) seleccione inc ... –

Cuestiones relacionadas