Saber Amani
Saber Amani

Reputation: 6489

Want to use LINQ instead of foreach but it doesn't work

In the following code foreach loop works fine, but when I try to use LINQ instead of using foreach it doesn't work no exception no error.

This code is working :

    public static IEnumerable<PatternInfo> LoadPatterns() {
        var directoryInfo = new DirectoryInfo(PatternFullPath);
        var dirs = directoryInfo.EnumerateDirectories();
        var result = new List<PatternInfo>();
        foreach (var info in dirs)
        {
            result.Add(new PatternInfo
                           {
                               PatternName = info.Name,
                               TemplateFileNames = GetTemplateFiles(info.FullName)
                           });
        }
        return result;
    }

But this one not :

    public static IEnumerable<PatternInfo> LoadPatterns() {
        var directoryInfo = new DirectoryInfo(PatternFullPath);
        var dirs = directoryInfo.EnumerateDirectories();
        var patterns = dirs.Select(info => new PatternInfo {
            PatternName = info.Name,
            TemplateFileNames = GetTemplateFiles(info.FullName)
        });
        return patterns;
    }

Any advice will be helpful.

Upvotes: 1

Views: 1030

Answers (3)

CassOnMars
CassOnMars

Reputation: 6181

LINQ is deferred execution. You're returning the statement, but it doesn't get evaluated until you do something to iterate over the IEnumerable you're returning. What is the code that calls LoadPatterns()?

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1039508

Well, enumerables are lazy until someone starts enumerating over them, so:

foreach (var item in LoadPatterns())
{
    ...
}

The .Select statement in your second example simply returns a new IEnumerable<T> but until there is some code that consumes/loops over this enumerable nothing will actually execute.

Upvotes: 2

BrokenGlass
BrokenGlass

Reputation: 161012

The difference between the two is that in the first code sample you have a List<PatternInfo>, all items in the list are populated already - then you return this list as IEnumerable<PatternInfo>.

In the second example you have a IEnumerable<PatternInfo> - this will only load the patterns when you iterate over the enumeration for the first time.

If you want the second version to be equivalent (eager loading of the patterns) then add a ToList():

return patterns.ToList();

Upvotes: 6

Related Questions