Nested Iterators & C# 3.0 yeilds problems?

A

Andrew Matthews

Hi All,
I have the following little class of iterators that allow me to iterate over
elements in the file system. I have nested some of them, and then added Func<FileInfo,
bool> delegates to filter out unwanted files. I get an InvalidProgramException
and haven't (yet) been able to find out what's going on. Do you have any
ideas?

TIA

Andrew Matthews
========================================

public class FsIter
{
public static IEnumerable<DirectoryInfo> SubDirectories(DirectoryInfo
di)
{
yield return di;
foreach (DirectoryInfo directory in di.GetDirectories())
{
foreach (DirectoryInfo subDirectory in SubDirectories(directory))
{
yield return subDirectory;
}
}
}

public static IEnumerable<FileInfo> AllFilesUnder(DirectoryInfo d)
{
foreach (DirectoryInfo dir in SubDirectories(d))
{
foreach (FileInfo fileInfo in dir.GetFiles())
{
yield return fileInfo;
}
}
}

public static IEnumerable<FileInfo> MatchingFilesUnder(Func<FileInfo,
bool> x, DirectoryInfo d)
{
foreach (FileInfo fileInfo in AllFilesUnder(d))
{
if (x(fileInfo))
yield return fileInfo;
}
}

public static IEnumerable<FileInfo> FilesByExtension(string ext,
DirectoryInfo d)
{
Func<FileInfo, bool> test = x=>x.Extension==ext;
return Match(test, AllFilesUnder(d));
}

public static IEnumerable<IT> Match<IT>(Func<IT, bool> test, IEnumerable<IT>
col)
{
foreach (IT it in col)
{
if(test(it))
yield return (it);
}
}
}

I tried to exercise it with the following:

[Test]public void TestIterateTestDir2()
{
string testdir = @"C:\etc\dev\fstags\src\UnitTests\tests";
List<FileInfo> files = new List<FileInfo>(FsTags.Core.FsIter.FilesByExtension(".txt",
new DirectoryInfo(testdir)));
Assert.AreEqual(files.Count, 4);
}

And I got the following:

System.InvalidProgramException: Common Language Runtime detected an invalid
program.
at FsTags.Core.FsIter.FilesByExtension(String ext, DirectoryInfo d)
at fstags.UnitTests.TestFsIter.TestIterateTestDir2() in TestFsIter.cs:line
26

I am running C# 3.0 May CTP (LINQ preview) and ReSharper 2.0 (2005)
 
B

Barry Kelly

Andrew Matthews said:

You have posted to 5 different newsgroups. Don't you think that
..languages.csharp would have sufficed?
I get an InvalidProgramException

I have adapted your source code to be a complete, compiling sample. It
does not generate an InvalidProgramException. Can you create a complete,
compiling sample which produces the error?

---8<---
using System;
using System.IO;
using System.Query;
using System.Collections.Generic;

public class App
{
public static IEnumerable<DirectoryInfo>
SubDirectories(DirectoryInfo di)
{
yield return di;
foreach (DirectoryInfo directory in di.GetDirectories())
foreach (DirectoryInfo subDirectory in
SubDirectories(directory))
yield return subDirectory;
}

public static IEnumerable<FileInfo> AllFilesUnder(DirectoryInfo d)
{
foreach (DirectoryInfo dir in SubDirectories(d))
foreach (FileInfo fileInfo in dir.GetFiles())
yield return fileInfo;
}

public static IEnumerable<FileInfo>
MatchingFilesUnder(Func<FileInfo,bool> x, DirectoryInfo d)
{
foreach (FileInfo fileInfo in AllFilesUnder(d))
if (x(fileInfo))
yield return fileInfo;
}

public static IEnumerable<FileInfo> FilesByExtension(string ext,
DirectoryInfo d)
{
Func<FileInfo, bool> test = x=>x.Extension==ext;
return Match(test, AllFilesUnder(d));
}

public static IEnumerable<IT> Match<IT>(Func<IT, bool> test,
IEnumerable<IT> col)
{
foreach (IT it in col)
if(test(it))
yield return (it);
}

static void Main()
{
string testdir = @"C:\Program Files";
List<FileInfo> files =
new List<FileInfo>(FilesByExtension(".txt",
new DirectoryInfo(testdir)));
Console.WriteLine(files.Count);
}
}
--->8---
I am running C# 3.0 May CTP (LINQ preview) and ReSharper 2.0 (2005)

I am running C# 8.00.50916 on 2.0.50727.

-- Barry
 
A

Andrew Matthews

Hello Barry,

Considering that I wasn't sure whether the problem was with C# specifically
or with the CLR I thought I wouldn't take any chances of getting a response.
As for compiling code that gives the error - that was what I posted.

Andrew
 
B

Barry Kelly

Andrew Matthews said:
As for compiling code that gives the error - that was what I posted.

The code you posted doesn't have a Main method - how can it compile and
produce the error? Did you try the code I posted? How is it different
from your code? Does the code I post show the error on your machine?

A complete sample is described here:

http://www.yoda.arachsys.com/csharp/complete.html

-- Barry
 
A

Andrew Matthews

Hello Barry,

I was using NUnit - I didn't need a main method.
My reason for posting the question was to try to find out what it was about
my code that caused the invalid IL.

Andrew
 
B

Barry Kelly

Andrew Matthews said:
I was using NUnit - I didn't need a main method.

You didn't need a main method, but what about the people you're asking
for help? Do you expect everybody to infer that you are using NUnit,
psychically figure out your version, download it, install it, and modify
your code to execute under NUnit (your code uses namespaces etc.), add
NUnit to the project references, and execute it under NUnit?

Or do you expect them to do what I did - i.e. convert the code into a
complete compiling sample - only to find that it does not perform as you
advertised: it does not cause invalid IL?

I would love help you find a bug is C# 3.0 May release. The trouble is,
you haven't given enough information.
My reason for posting the question was to try to find out what it was about
my code that caused the invalid IL.

The code you provided, to the best of my knowledge, does *not* cause
invalid IL. You'll have to produce a complete, compiling sample if you
are to have any hope of anyone helping you with your problem.

-- Barry
 
N

Nicholas Paldino [.NET/C# MVP]

Andrew,

LINQ doesn't require a change to the CLR to work. It is most likely an
issue with the compiler (which is to be expected, as this is a CTP, not even
a beta).

Post a complete example (meaning, no nunit, etc, etc) and we can try it
out, and then if it is an error with the compiler, you can post it to the
product feedback center.

Hope this helps.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top