Предикаты и OrderBy, Func - PullRequest
       20

Предикаты и OrderBy, Func

3 голосов
/ 04 августа 2010

Я понимаю, что предикаты являются делегатом функции, которая возвращает bool и принимают общий параметр, я понимаю, что когда я говорю:

mycustomer => mycustomer.fullname == 1

Это на самом деле означает:

delegate (Customer mycustomer)
{
  return mycustomer.fullName == "John";
}

ПараметрЯ передаю, когда я передаю это лямбда-выражение:

public delegate bool Criteria<T>(T value), которое изначально называется предикатом

Но я не понимаю, что это значит, когда я говорю mycustomer=>mycustomer.fullname

В customers.OrderBy(mycustomer=>mycustomer.fullname);

Как мне реализовать что-то вроде OrderBy?Как мне сообщить методу, над каким свойством действовать?как в предыдущем примере?

В качестве примера в данном случае я хочу создать метод, который получит все значения коллекции для определенного свойства:

list<string> mylist = customers.GetPropertyValues(cus=>cus.Fullname);

Заранее спасибо.

Ответы [ 4 ]

3 голосов
/ 04 августа 2010

Вы можете создать что-то вроде этого:

static class ExtenstinonClass
{
    static IEnumerable<V> GetPropertyValues<T, V>(this IList<T> collection, Func<T, V> func)
    {
        foreach(var item in collection)
        {
            yield retun func(item);
        }
    }
}

Но я действительно не понимаю, почему метод Select вам не подходит.

3 голосов
/ 04 августа 2010

Func<TElement,TKey> используется для создания IComparer<TKey>, который используется внутри OrderedEnumerable для сортировки элементов.Когда вы делаете:

var items = myList.OrderBy(i => i.SomeProperty);

Тип OrderedEnumerable создает IComparer<TKey> внутри.В приведенном выше примере, если бы i.SomeProperty было String, это создаст экземпляр IComparer<String>, а затем отсортирует элементы в перечисляемом источнике с помощью этого компаратора на элементе SomeProperty.последний случай:

list<string> mylist = customers.GetPropertyValues(cus=>cus.Fullname);

Вы делаете это, используя Select:

var names = customers.Select(c => c.Fullname);

, который будет возвращать перечислимое из String имен.В методе Select Func<TSource, TResult> используется для выбора целевого элемента, который будет добавлен к результату.

Чтобы скопировать это самостоятельно, вы можете сделать:

public static IEnumerable<TMember> GetPropertyValues<TSource, TMember>
  (this IEnumerable<TSource> enumerable, Func<TSource, TMember> selector)
{
  if (enumerable == null)
    throw new ArgumentNullException("enumerable");

  foreach (TSource item in enumerable)
  {
    yield return selector(item);
  }
}
2 голосов
/ 04 августа 2010

но я не понимаю, что это значит, когда я говорю mycustomer => mycustomer.fullname

Это то же самое, что и ваш пример делегата, за исключением того, что он возвращает только fullName.Передается как лямбда, чтобы его можно было вычислить лениво.

Если вы хотите создать метод, который работает как OrderBy, кроме того, что ваш GetPropertyValues ​​выглядит так же, как customers.Select(c => c.Fullname), то выдолжны погрузиться в море обобщений и методов расширения.OrderBy - это на самом деле просто метод расширения для IEnumerable, определяемый как

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
)

Похоже, ответ @Mike является примером этого, а также повторной реализацией LINQ Select.

2 голосов
/ 04 августа 2010

OrderBy Extension Method для класса Enumerable принимает метод типа Func в качестве аргумента. Здесь - документация.

Здесь - еще одна хорошая статья, которую вы можете использовать.

...