doiley
doiley

Reputation: 140

XElement.Elements().Select() Causes Try specifying the type arguments explicitly

I'm having a weird issue and was wondering what might be causing it.

I have the following XML:

<categories>
  <category Name="Generic" Id="0"></category>
  <category Name="Development Applications" Id="2"></category>
  <category Name="Standard Templates" Id="5"></category>      
  <category Name="Testing" Id="9" />
</categories>

and the following code to create a list of 'categories':

var doc = XDocument.Load("categories.xml");

var xElement = doc.Element("categories");
if (xElement == null) return;

var categories = xElement.Elements().Select(MapCategory).ToList();

where:

private static Category MapCategory(XElement element)
{
    var xAttribute = element.Attribute("Name");
    var attribute = element.Attribute("Id");
    return attribute != null && xAttribute != null 
        ? new Category(xAttribute.Value, attribute.Value) 
        : null;
}

before compiling there aren't any errors/warnings etc that this is wrong, however i get the following message once compiled but still without the red underline:

The type arguments for method 'System.Linq.Enumerable.Select<TSource,TResult>(System.Collections.Generic.IEnumerable, System.Func<TSource,TResult>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Now if i change the line in question to the following, all is well:

var categories = xElement.Elements().Select<XElement, Category>(MapCategory).ToList();

I would have thought that Select<XElement, Category> was redundant??? And ReSharper also agrees with me.

Just to make sure, I removed the MapCategory and replaced it with the following but this time I get the red underline and a compliation error:

var categories2 = doc.Element("categories").Elements().Select(element =>
            { new Category(element.Attribute("Name").Value, element.Attribute("Id").Value); }).ToList();

Just to add to my confusion, I had another developer also try the code out and he didn't get any compilation errors at all.

Any ideas why this might be happening?

Upvotes: 2

Views: 3629

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1502336

Just to add to my confusion, I had another developer also try the code out and he didn't get any compilation errors at all.

My guess is that you're using a different version of the C# compiler to your colleague.

This isn't limited to LINQ to XML, or the use of the Elements() call. I'm sure you'll see the same behaviour if you have:

private static string ConvertToString(int x) { ... }

...
IEnumerable<int> values = null; // We're only testing the compiler here...
IEnumerable<string> strings = values.Select(ConvertToString);

Basically, type inference for generic method invocations using method group conversions was improved in the C# 4 compiler. (I think it may have improved for the C# 5 compiler as well, but I can't remember for sure.) An alternative to specifying the type arguments explicitly is to use a lambda expression:

...Elements().Select(x => MapCategory(x))...

Upvotes: 3

Related Questions