【问题标题】:Predicates and OrderBy , Func谓词和 OrderBy , 函数
【发布时间】:2010-08-04 07:56:30
【问题描述】:

我知道谓词是委托给返回 bool 并采用泛型参数的函数,当我说:

mycustomer => mycustomer.fullname == 1

其实意思是:

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

我在传递这个 lambda 表达式时传入的参数是:

public delegate bool Criteria<T>(T value) 原生称为谓词

但是我不明白我说mycustomer=>mycustomer.fullname是什么意思

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

如何实现OrderBy 之类的东西?如何告诉方法对哪个属性执行操作!和前面的例子一样吗?

举个例子,我想创建一个方法来获取特定属性的集合的所有值:

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

提前致谢。

【问题讨论】:

  • Predicate 是一个返回 bool 的函数。 mycustomer=&gt;mycustomer.fullnameFunc&lt;Cutomer, string&gt;(我猜 fullnamestring 类型)。您应该阅读迭代器(IEnumerable、yield、...)。如果您正在使用数据库等 - 一切都与表达式树有关。

标签: c# lambda predicate func


【解决方案1】:

Func&lt;TElement,TKey&gt; 用于创建IComparer&lt;TKey&gt;,在OrderedEnumerable 内部使用该OrderedEnumerable 对项目进行排序。当你这样做时:

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

OrderedEnumerable 类型在内部创建一个IComparer&lt;TKey&gt;。在上面的示例中,如果i.SomePropertyString,它将创建IComparer&lt;String&gt; 的实例,然后使用SomeProperty 成员上的比较器对源枚举中的项目进行排序。

在你的最后一种情况下:

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

您可以使用Select

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

这将返回一个可枚举的String 名称。在Select 方法中,Func&lt;TSource, TResult&gt; 用于选择要添加到结果中的目标元素。

要自己复制,您可以这样做:

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

【讨论】:

  • 非常感谢您的回复,但我知道我可以使用 customers.select(c=>c.fullname) 我只是想知道如何实现类似的东西,我实际上并不是在寻找获取价值我只是举一个例子,问题是如何实现一个方法,比如customers.GetPropertyValues(cus=>cus.Fullname);或customers.Select(c => c.Fullname);任何可以使用 lambda 表达式指定属性名称的方法。
【解决方案2】:

但我不明白的是当我说 mycustomer=>mycustomer.fullname 时是什么意思

这与您的委托示例相同,只是它只返回全名。作为 lambda 传递,以便对其进行惰性求值。

如果你想创建一个像OrderBy 一样工作的方法,而且你的GetPropertyValues 似乎与customers.Select(c =&gt; c.Fullname) 相同,那么你将不得不潜入泛型和扩展方法的海洋。 OrderBy 实际上只是IEnumerable 上的扩展方法,定义为

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

看起来@Mike 的答案就是一个例子,也是 LINQ Select 的重新实现。

【讨论】:

    【解决方案3】:

    你可以创建这样的东西:

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

    但我真的不明白为什么 Select 方法不适合你。

    【讨论】:

    • 我不反对 select 方法,问题是它不回答问题,但你的回答可以!我接受了你的回答,非常感谢,非常好
    【解决方案4】:

    OrderBy Extension MethodEnumerable 上的 OrderBy Extension Method 采用 Func 类型的方法作为参数。 Here 是文档。

    Here 是另一篇您可以使用的好文章。

    【讨论】:

    • 不错的帖子 Decy,这个答案真的很好,表达式树就是我要找的,谢谢...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-02
    • 2014-05-20
    • 1970-01-01
    • 2020-06-20
    相关资源
    最近更新 更多