Following my last post on benchmarking madness, here is a short one about finding .net classes or interfaces based on given criteria.

While writing my last post, I found myself having a hard time searching for classes implementing IEnumerable<T> without also implementing ICollection<T>.
Indeed, beside String, there is not so many…

This information is almost impossible to determine from msdn, where I first sought, and my friend Google was not very helpful this time.

I nevertheless stumbled upon a nice post doing more or less the job.

I modified it to match only public classes implementing IEnumerable<T> without implementing ICollection, IList, or there generic counterparts:

static void Main(string[] args)
{
	var typesIEnum = AppDomain.CurrentDomain
	   .GetAssemblies()
	   .SelectMany(x => x.GetTypes())
	   .Where(x =>
		   {
			   var interfaces = x.GetInterfaces();
			   bool result = true;
			   result &= !x.IsAbstract && !x.IsInterface;
			   result &= x.IsPublic;
			   result &= interfaces.Select(t => t.GUID).Contains(typeof(IEnumerable<>).GUID);
			   result &= !interfaces.Select(t => t.GUID).Contains(typeof(ICollection<>).GUID);
			   result &= !interfaces.Select(t => t.GUID).Contains(typeof(ICollection).GUID);
			   result &= !interfaces.Select(t => t.GUID).Contains(typeof(IList<>).GUID);
			   result &= !interfaces.Select(t => t.GUID).Contains(typeof(IList).GUID);
			   return result;
		   })
		   .OrderBy(x => x.FullName);
	Console.WriteLine("{0} result(s):", typesIEnum.Count());
	foreach (var type in typesIEnum)
	{
		Console.WriteLine(type.FullName);
	}
	Console.ReadLine();
}

Oddly enough, I had to do the type comparisons using the GUID property, because typeof(ICollection) for example, is not equal to the ICollection type returned by the GetInterfaces() method, which FullName property is null

Anyway, here are the results:

5 result(s):
System.Linq.EnumerableQuery`1
System.Linq.Lookup`2
System.Linq.OrderedParallelQuery`1
System.Linq.ParallelQuery`1
System.String

Not so many, I told you :p

Keep in mind though, these results may (and surely would) change when importing more references.
In this case, I only imported System and System.Core in a Console project targeting .Net Framework 4.0.

Also, if you allow for non public classes, the count jumps to 141!
(most of them being in the System.Linq namespace…)