如何使用Linq获取IEnumerable中的项目

时间:2011-12-12 16:06:51

标签: c#

你会如何重构这种方法?

    private bool IsTermExist(string word)
    {
        var query = from term in m_xdoc.Descendants("Term")
                    where term.Attribute("Name").Value.ToUpper().Contains(word.ToUpper())
                    select term;

        return query.Any();
    }

3 个答案:

答案 0 :(得分:6)

我可能会使用接受谓词的Any重载:

private bool TermExists(string word)
{
    return m_xdoc.Descendants("Term")
       .Any(term => term.Attribute("Name").Value
                        .IndexOf(word, StringComparison.OrdinalIgnoreCase) >= 0);
}

注意:

  • 使用ToUpper表示不区分大小写(例如,由于土耳其语中的行为,大多数开发人员都意外);使用overload of IndexOf which takes a StringComparison是首选。 (Equals有类似的重载。)
  • 如果我们 要与word.ToUpper()进行比较,我们可以提取它,以便word.ToUpper()只执行一次,而不是每Term个元素执行一次。 (除了微优化之外,我认为首先提取查询的迭代不变部分通常是个好主意。但是不要期望在这方面保持一致性:)
  • 对于没有Term属性的Name元素,此代码仍会响起。这可能是也可能不是你想要的。

答案 1 :(得分:1)

如果要返回第一个匹配项而不是返回项的方法或未找到null的方法:

private XElement? GetTerm(string word)
{
      var query = from term in m_xdoc.Descendants("Term")
                  where term.Attribute("Name").Value.ToUpper().Contains(word.ToUpper())
                  select term;

      return query.FirstOrDefault();
}

答案 2 :(得分:1)

我可能会这样写:

private static bool MatchesName(XElement el, string name)
{
    var attr = el.Attribute("Name");
    return attr.Value.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0;
}

private bool TermExists(string word)
{
    return m_xdoc.Descendants("Term").Any(e => MatchesName(e, word));
}

很难说在没有看到其他代码的情况下在哪里拆分帮助方法。