【问题标题】:Passing a lambda expression as parameter to a method?将 lambda 表达式作为参数传递给方法?
【发布时间】:2015-06-09 14:25:20
【问题描述】:

这似乎是一个常见的要求,但我无法在任何地方找到解决方案。

我有一个方法可以OrderBy 一个集合,具体取决于传递给它的参数。

我想将“OrderBy”的内容传递给该方法,但不知道该怎么做。

我的尝试

我尝试了一个带字符串的开关(即,如果您传递“名称”,它会点击按名称排序的 case),但这感觉“笨拙”且没有必要。

我知道它类似于Func<TEntity, TResult>,但我不能完全破解它。

伪代码:

GetOrderedCollection([NOT SURE] orderBy)
{
  return collection.OrderBy(orderBy);
}

【问题讨论】:

  • 为什么不看看 OrderBy 实际采用的参数,并为您的方法使用相同的参数类型?

标签: c# linq collections parameters lambda


【解决方案1】:

OrderBy 是具有以下签名的扩展方法:

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

(来源:https://msdn.microsoft.com/it-it/library/bb534966%28v=vs.110%29.aspx

所以你的方法需要一个 Func 作为它的参数,其中 TSource 是 List 类型,而 TKey 是你的 lambda 返回的类型。 一个例子是:

public void Method<TSource, TKey>(List<TSource> list, Func<TSource, TKey> func)
        {
            ...
            IOrderedEnumerable<TSource> orderedEnumerable = list.OrderBy(func);
        }

编辑: 我还注意到,在您的示例代码中,您将方法声明为 void,然后您尝试返回 IOrderedEnumerable。 如果你想取回有序集合,你的方法至少需要一个 IEnumerable 类型(但这会破坏排序的目的,因为 IEnumerables 不保证顺序。更可能的实现是返回一个List&lt;TSource&gt;并致电list.OrderBy(func).ToList()

【讨论】:

    【解决方案2】:

    在最通用的形式中,您的方法需要如下所示:

    IOrderedEnumerable<T1> GetOrderedCollection<T1, T2>(IEnumerable<T1> collection, Func<T1, T2> orderBy)
    {
        return collection.OrderBy(orderBy);
    }
    

    T1 是列表中项目的类型,T2 是您要订购的 T1 的属性类型。

    【讨论】:

      【解决方案3】:

      这是否满足您的要求?

          static void Main(string[] args) {           
              var objects = new List<Test>();
              GetOrderedCollection(objects, x => x.Name);
          }
      
          class Test {
              public string Name { get; set; }
          }
      
          static IEnumerable<TEntity> GetOrderedCollection<TEntity>(IEnumerable<TEntity> objects, Func<TEntity, object> orderBy) {
              return objects.OrderBy(orderBy);
          }
      

      【讨论】:

        【解决方案4】:

        是的,您正在寻找Func&lt;TEntity, TResult&gt; orderingFunc。重要的是输出(TResult)是一个IComparable,以便OrderBy 函数可以正确地对您的结果进行排序。

        所以这样的事情可以正常工作:

        public void OrderByDynamic(Func<Model, object> orderByFunc)
        {
            collection = collection.OrderBy(orderByFunc); //don't forget to assign the return value
        }
        

        你可以像平常一样使用 lambda 函数来调用它:

        OrderByDynamic(m => m.SortObj); //as long as this property/return value is IComparable
        

        A .NET Fiddle 展示了这个想法

        【讨论】:

          【解决方案5】:

          参数必须是FuncAction。有关详细信息,请参阅this question 的答案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-12-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-08-21
            • 1970-01-01
            相关资源
            最近更新 更多