Breaking the C# compiler, again
Take a look at the following code:
1: var docs = new dynamic[0];2: var q = from doc in docs3: where doc["@metadata"]["Raven-Entity-Name"] == "Cases"4: where doc.AssociatedEntities != null5: from entity in doc.AssociatedEntities6: where entity.Tags != null // COMPILER ERROR HERE7: from tag in entity.Tags8: where tag.ReferencedAggregate != null9: select new {tag.ReferencedAggregate.Id, doc.__document_id};
It doesn’t compiles, complaining about an error in line 6 (The property '<>h__TransparentIdentifier0' cannot be used with type arguments).
Leaving aside the issue with the error itself, which is about as useful as C++ template errors, I have a strongly issue with this.
What do you think can fix this error? Well, if you remove line 8 (!), it just works:
1: var docs = new dynamic[0];2: var q = from doc in docs3: where doc["@metadata"]["Raven-Entity-Name"] == "Cases"4: where doc.AssociatedEntities != null5: from entity in doc.AssociatedEntities6: where entity.Tags != null7: from tag in entity.Tags8: select new { tag.ReferencedAggregate.Id, doc.__document_id };
There are several things that I can’t figure out:
- Why am I getting an error?
- Why removing a line after the error fixes the error in the line before it.
What I suspect is that the error reporting (which in C# is usually damn good) is getting confused with the error reporting location.
To make things worse, this code will crash VS 2010 every single time. I am actually editing this in notepad!!!
Here is the set of extensions methods that I use here:
public static class LinqOnDynamic { private static IEnumerable<dynamic> Select(this object self) { if (self == null) yield break; if (self is IEnumerable == false || self is string) throw new InvalidOperationException("Attempted to enumerate over " + self.GetType().Name); foreach (var item in ((IEnumerable) self)) { yield return item; } } public static IEnumerable<dynamic> SelectMany(this object source, Func<dynamic, int, IEnumerable<dynamic>> collectionSelector, Func<dynamic, dynamic, dynamic> resultSelector) { return Enumerable.SelectMany(Select(source), collectionSelector, resultSelector); } public static IEnumerable<dynamic> SelectMany(this object source, Func<dynamic, IEnumerable<dynamic>> collectionSelector, Func<dynamic, dynamic, dynamic> resultSelector) { return Enumerable.SelectMany(Select(source), collectionSelector, resultSelector); } public static IEnumerable<dynamic> SelectMany(this object source, Func<object, IEnumerable<dynamic>> selector) { return Select(source).SelectMany<object, object>(selector); } public static IEnumerable<dynamic> SelectMany(this object source, Func<object, int, IEnumerable<dynamic>> selector) { return Select(source).SelectMany<object, object>(selector); } }
WTF?!

Comments
Comment preview