0

How can I put the following loops into one Linq query? The end result that I am trying to achieve is getting a list of Statements that are in those class methods.

Context: For every class, the corresponding methods are fetched with the classname. With every combination of classname / method name, I can call the metadata to get the source code (string). Then I compile that string and that Results in Method object that has and IEnumerable containing all of the code statements of that method. So I was to get the list of statements across all classes and methods.

        IXppcMetadataProvider serviceMetadataProvider = Program.getXppcMetadataProvider();

        IEnumerable<string> classNames = serviceMetadataProvider.ClassNames();

        MultipassAdministrator multipassAdmin = new MultipassAdministrator(serviceMetadataProvider);


        foreach (string className in classNames)
        {
            IEnumerable<string> classMethods = serviceMetadataProvider.ClassMethods(className);

            foreach (string methodName in classMethods)
            {
                string source = serviceMetadataProvider.GetClassMethodSource(className, methodName);

                Method method = multipassAdmin.CompileSingleMethod(source) as Method;

                if (method != null)
                {
                    foreach (Statement statement in method.Statements)
                    {
                        System.Console.WriteLine(statement.ToString());
                    }
                }
            }
        }
0

2 Answers 2

1

Basically you need to use the following Linq methods that act like higher order functions

System.Console.WriteLine(
    String.Join(Environment.NewLine,
                getXppcMetadataProvider().ClassNames().SelectMany(
                    className => getXppcMetadataProvider().ClassMethods(className)
                    .Select(
                        methodName => getXppcMetadataProvider()
                        .GetClassMethodSource(className, methodName)
                    ).Select(
                        source => new MultipassAdministrator(getXppcMetadataProvider())
                        .CompileSingleMethod(source) as mymeth)
                )
                .Where(method => method != null).SelectMany(
                    method => method.Statements
                ).Select(statement => statement.ToString())

               ));

Select when you have a 1 to 1 correspondence, as opposite to SelectMany, that would correspond to bind in Haskell.

Notice that is straightforward to get function composition in Linq, as shown above.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I was close to that, but no sigar.. Your solution did it!
0

Converting to the query syntax is easier, but LINQ is slower and harder to debug/comprehend.

var q = from nothing in new[] { 0 }
        let serviceMetadataProvider = Program.getXppcMetadataProvider()
        let classNames = serviceMetadataProvider.ClassNames()
        let multipassAdmin = new MultipassAdministrator(serviceMetadataProvider)

        from className in classNames
        let classMethods = serviceMetadataProvider.ClassMethods(className)

        from methodName in classMethods
        let source = serviceMetadataProvider.GetClassMethodSource(className, methodName)
        let method = multipassAdmin.CompileSingleMethod(source) as Method
        where method != null

        from statement in method.Statements
        select statement.ToString();

System.Console.WriteLine(String.Join(Environment.NewLine, q));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.