Linq与string.Compare(...,...,...)混合

时间:2012-01-11 13:14:24

标签: linq

我正在寻找一个解决方案来使用linq查询并忽略大小写。我发现了这个:

m_context.Users.SingleOrDefault(u => string.Compare(u.UserName, username, StringComparison.InvariantCultureIgnoreCase) == 0);

它根据提供的用户名搜索用户对象,忽略大小写。它有效,这不是问题,但在分析代码时,我觉得很奇怪。我的意思是,在linq中,我们有string.Compare(...,...,...)返回一个整数。所以呢?它是如何由linq(SingleOrDefault)管理的?

感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

您正在将谓词传递给SingleOrDefault方法。谓词的计算结果为true或false,此方法返回满足该谓词的序列中的单个元素。

u => string.Compare(x, y, StringComparison.InvariantCultureIgnoreCase) == 0

这是一个Func<User, bool>谓词,这意味着它是一个接受User作为参数u的函数,并返回一个布尔值作为string.Compare(...) == 0求值的结果。然后返回满足此条件的用户序列中的单个元素。如果不止一个满足谓词,那就是错误。如果少于一个满足谓词,则获得该类型的默认值,对于引用类型,该默认值为null。

将其视为非常粗略

public static T SingleOrDefault<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
     T foundItem = null;
     int count = 0;

     foreach (T item in sequence)
     {
          if (predicate(item)) // evaluates the u => string.Compare(...)
          {
               count += 1;
               if (count > 1)
                   throw new InvalidOperationException("...");

               foundItem = item;
          }
     }

     return foundItem;
}

以上只是我对该方法所做的粗略草案,而不是实际的实现。如果您对更深入地研究linq-to-objects实现感兴趣,请考虑阅读Jon Skeet的Edulinq系列,在那里他经历并重新实现每个(给予或采取)方法并在此过程中解释它。同样,这不是图书馆的实际源代码,但它非常有教育意义。

答案 1 :(得分:1)

您有string.Compare(...) == 0 - 那是Boolean