传递作为参数传入的谓词



我在将谓词传递给另一个函数时遇到问题。此谓词将作为尝试调用第二个函数的参数传入。下面是一个代码片段。

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

我一直在尝试以各种不同的方式更改参数,试图使其工作,但我没有任何成功。也许我不明白为什么编译器认为"谓词"与GetList()期望的不同。

编辑:更多信息

ReportPart : ContentPart<ReportRecord>
ReportRecord : ContentPartRecord

ContentPart 和 ContentPartRecord 都是基类

调用方到构建模型

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

构建模型

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

获取列表

 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)你正在做的事情确实是错误的,编译器正在拯救你,2)你正在做的事情不能证明是正确的,所以你必须向编译器承诺你知道你在做什么。

如果你属于第一类,那么一切都会丢失。你不能让它工作。

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

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


也就是说,虽然以这种方式编写代码可能有一些重要原因,但考虑到您到目前为止展示的少量代码,您还不清楚为什么您尝试采用泛型谓词并将其强制为特定类型。

根据代码其余部分的实际情况,像这样的一对泛型方法在以下情况下会更好:1)完全泛型(即不要在调用GetList()时强制类型ReportRecord),或2)你根本不打扰泛型类型(即省略TPart并从BuildModel()方法中TRecord)。

示例 1):

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

示例 2):

public IEnumerable<ViewModel> BuildModel(
    Expression<Func<ReportRecord, bool>> predicate)
{
    IEnumerable<ReportPart> items = GetList<ReportPart, ReportRecord>(predicate);
}

混合和匹配,即使你可以让它正常工作,通常也表明架构中存在更根本的问题,泛型要么被用在不应该的地方,要么没有被充分利用。


如果上述内容不能让你回到正轨,你真的应该通过提供一个最小、完整的代码示例来改进问题。

相关内容

  • 没有找到相关文章

最新更新