XElement.Elements()。Select()原因尝试显式指定类型参数

时间:2012-09-11 00:38:06

标签: c# linq-to-xml

我遇到了一个奇怪的问题,并且想知道可能导致它的原因。

我有以下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>

以及以下代码来创建“类别”列表:

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

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

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

其中:

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;
}

在编译之前没有任何错误/警告等这是错误的,但是我在编译后得到以下消息,但仍然没有红色下划线:

  

无法从用法推断出方法'System.Linq.Enumerable.Select&lt; TSource,TResult&gt;(System.Collections.Generic.IEnumerable,System.Func&lt; TSource,TResult&gt;)'的类型参数。尝试明确指定类型参数。

现在如果我将有问题的行更改为以下内容,那么一切都很顺利:

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

我原以为Select<XElement, Category>是多余的??? 而ReSharper也同意我的意见。

为了确保,我删除了MapCategory并将其替换为以下内容,但这次我得到了红色下划线和一个compliation错误:

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

只是为了增加我的困惑,我让另一个开发人员也尝试了代码,他根本没有得到任何编译错误。

为什么会发生这种情况的任何想法?

1 个答案:

答案 0 :(得分:3)

  

只是为了增加我的困惑,我让另一个开发人员也尝试了代码,他根本没有得到任何编译错误。

我的猜测是你正在为你的同事使用不同版本的C#编译器。

这不仅限于LINQ to XML,也不限于使用Elements()调用。如果你有:

,我相信你会看到同样的行为
private static string ConvertToString(int x) { ... }

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

基本上,使用方法组转换的泛型方法调用的类型推断在C#4编译器中得到了改进。 (我认为可能也为C#5编译器做了改进,但我无法确定。)明确指定类型参数的另一种方法是使用lambda表达式:

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