2012-01-11 3 views
2

Я искал решение, чтобы перенести запрос linq и игнорировать его. Я нашел это:Linq mixed with string.Compare (..., ..., ...)

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

Он ищет объект пользователя на основе предоставленного имени пользователя, игнорируя регистр. Это работает, это не вопрос здесь, но при анализе кода мне кажется странным. Я имею в виду, внутри linq у нас есть string.Compare (..., ..., ...), возвращающий целое число. И что? Как это управляется linq (SingleOrDefault)?

Благодарим за помощь.

ответ

4

Вы передаете предикат в метод SingleOrDefault. Предикат оценивает значение true или false, и этот метод возвращает одиночный элемент в последовательности, которая удовлетворяет этому предикату.

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

Это Func<User, bool> предикат, который означает, что это функция, которая принимает пользователя в качестве аргумента 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, где он проходит и перерабатывает каждый метод (дайте или возьмите) и объяснит его на этом пути. Опять же, это не фактический исходный код библиотеки, но это очень образовательный.

+0

Большое спасибо. Это очень ясно для меня. – Bronzato

1

Вы string.Compare(...) == 0 - это Boolean