传递作为参数传入的谓词

时间:2015-06-10 03:20:46

标签: c# linq parameters predicate

我在将谓词传递给另一个函数时遇到了麻烦。该谓词将作为试图调用第二个函数的参数传入。以下是代码段。

public IEnumerable<ViewModel> BuildModel<TPart, TRecord>(Expression<Func<TRecord, bool>> predicate) 
                where TPart : ContentPart<TRecord>
                where TRecord : ContentPartRecord
            {
                IEnumerable<ReportPart> items = GetList<ReportPart, ReportRecord>(predicate);

这个问题是谓词参数,在调用GetList()时它会一直出错,说调用有一些无效的参数。获取列表调用是:

 public IEnumerable<TPart> GetList<TPart, TRecord>(Expression<Func<TRecord, bool>> predicate)
            where TPart : ContentPart<TRecord>
            where TRecord : ContentPartRecord

我一直试图通过一系列不同的方式来改变参数,试图让它发挥作用,但我还没有取得任何成功。也许我不明白为什么编译器会认为&#39;谓词&#39;与GetList()期待的不同。

编辑:更多信息

ReportPart : ContentPart<ReportRecord>

ReportRecord : ContentPartRecord

ContentPart和ContentPartRecord都是基类

调用者到BuildModels

List<ReportViewModel> model = _service.BuildReports<ReportPart, ReportRecord>(x => x.Id == 1).ToList();

BuildModels

public IEnumerable<ReportViewModel> BuildReports<TPart, TRecord>(System.Linq.Expressions.Expression<Func<TRecord, bool>> predicate)
            where TPart : ContentPart<TRecord>
            where TRecord : ContentPartRecord
{
            List<ReportViewModel> model = new List<ReportViewModel>();
            IEnumerable<ReportPart> reportParts = GetList<ReportPart, ReportRecord>(predicate);
            //do some stuff with reportParts
            return model;
    }
}

的GetList

 public IEnumerable<TPart> GetList<TPart, TRecord>(System.Linq.Expressions.Expression<Func<TRecord, bool>> filter)
            where TPart : ContentPart<TRecord>
            where TRecord : ContentPartRecord
        {
            return filter == null ?
                Services.ContentManager.Query<TPart, TRecord>().List() :
                Services.ContentManager.Query<TPart, TRecord>().Where(filter).List();
        }

1 个答案:

答案 0 :(得分:2)

如果没有a good, minimal, complete code example,就无法确定问题的最佳解决方案是什么,假设存在一个问题。

也就是说,差异问题通常有两种: 1)你正在做的事情确实是错误的,编译器正在拯救你, 2)你是什么“这样做是不可证明的,所以你必须向编译器保证你知道自己在做什么。”

如果你属于第一类,那么一切都会丢失。你无法让它发挥作用。

但如果您属于第二类,您可以通过将原始谓词包装在与被调用方法的要求兼容的新谓词中来接听您的工作:

IEnumerable<ReportPart> items =
    GetList<ReportPart, ReportRecord>(r => predicate((TRecord)r));


也就是说,虽然你可能有一些重要的原因让你以这种方式编写代码,但鉴于你到目前为止已经展示了一些代码,你为什么要尝试使用泛型谓词并强制它进入它并不是很清楚。特定类型。

根据其余代码中的实际情况,这样的一对通用方法在 1)完全通用的情况下效果更好(即不要强制类型为ReportRecord调用GetList() 2)你根本不打扰泛型类型(即省略TPart和{{1来自TRecord方法)。

1)的例子:

BuildModel()

2)的例子:

public IEnumerable<ViewModel> BuildModel<TPart, TRecord>(
    Expression<Func<TRecord, bool>> predicate) 
        where TPart : ContentPart<TRecord>
        where TRecord : ContentPartRecord
{
    IEnumerable<TPart> items = GetList<TPart, TRecord>(predicate);
}

混合和匹配,即使你能使它正常工作,也常常表明架构中存在一个更基本的问题,即泛型要么在不应该使用的地方使用,要么就是没有被使用优点以及它们应该是。


如果上述内容没有让您回到正轨,那么您应该通过提供最小的完整代码示例来改进问题。