传入可以为空的表达式<func <t,tresult =“”>&gt;?作为方法参数?</func <t,>

时间:2014-04-07 22:11:07

标签: c# lambda expression

所以我有一个方法

public IPagedList<MyObject> GetAll<T>(Expression<Func<MyObject, T>>? orderBy, 
    int pageNumber = 1, int pageSize = 10)
{
    return dataContext.MyObjects
      .OrderBy(orderBy.HasValue ? orderBy.Value : <WHAT GOES HERE?>)
      .ToPagedList<MyObject>(pageNumber, pageSize);
}

我的目标是让orderBy参数可选,如果orderBynull,则将订单默认为属性MyObject.Id

我已尝试.OrderBy(orderBy.Hasvalue ? orderBy.Value : x => x.Id)但收到此错误:

Type of conditional expression cannot be determined because there is no implicit conversion between 'System.Func<MyObject, T>' and 'lambda expression'

我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:3)

您的代码存在一些问题

  • Expression<TDelegate>是一个类,所以它已经可以为空;你可以简单地测试orderBy == nullNullable<T>有一个通用约束,T必须是struct,因此Expression<Func<MyObject, T>>?无法编译。
  • 接下来你会遇到这样的问题,因为T类型没有绑定在方法中,但x.Id是。Expression<Func<MyObject, T>>。换句话说,您将无法使用条件运算符在值Expression<Func<MyObject, int>>Id之间进行选择(假设intOrderBy)而仍然保持类型信息传递给public IPagedList<MyObject> GetAll<T>(Expression<Func<MyObject, T>> orderBy, int pageNumber = 1, int pageSize = 10) { IQueryable<MyObject> objects = dataContext.MyObjects; objects = (orderBy != null) ? objects.OrderBy(orderBy) : objects.OrderBy(x => x.Id); return objects.ToPagedList<MyObject>(pageNumber, pageSize); } 方法。

解决方案是使用以下内容:

OrderBy

条件运算符适用于此代码,因为无论您传递给IQueryable<MyObject>的内容是什么,返回类型都是相同的,orderBy

另请注意,您不能简单地为T传入空值,因为无法推断var results = MyClass.GetAll<int>(null); 。你必须这样称呼它:

orderBy

最终,您可能最好创建两个重载,一个接受{{1}}表达式,另一个不接受。{/ p>