Passing a predicate passed as a parameter

I am having trouble passing to another function predicate. This predicate would be passed as a parameter that tries to call the second function. Below is a code snippet.

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

      

This issue is the parameter of the predicate, when called, GetList()

it continues to erroneously stating that the call has some invalid arguments. Calling the Get list:

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

      

I've tried changing the parameter in a bunch of different ways, trying to get this to work, but I had no success. I may not understand why the compiler thinks the "predicate" is different from what is expected GetList()

.

EDIT: additional information

ReportPart : ContentPart<ReportRecord>

ReportRecord : ContentPartRecord

      

ContentPart and ContentPartRecord are base classes

Caller to 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();
        }

      

+3


source to share


1 answer


Without a good, minimal, complete code example , it is impossible to know exactly what is the best solution for your problem, assuming it exists at all.

However, deviation problems usually come in two flavors: 1) what you are doing is really wrong and the compiler saves you, and 2) that you "do not justify doing it, so you have to promise the compiler that you know what you are doing.

If you are in the first category, then all is lost. You cannot get this to work.

But if you're in the second category, you can make your call work by wrapping the original predicate in a new one that is compatible with the method's requirements:

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

      


That said, while it's possible that there is some important reason for writing code this way, given the little code you've shown so far, it's not entirely clear why you're trying to take a generic predicate and force it to be a specific type.

Depending on what's really going on in the rest of the code, a couple of generic methods like this will work better if you either 1) go all the way to the generic (i.e. don't force the type as ReportRecord

in the call GetList()

) or 2) you do not worry about general types (i.e., leave TPart

, and TRecord

on the method BuildModel()

).



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

      

Example 2):

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

      

Mixing and matching, even if you can get it to work correctly, is often a sign that there is a more fundamental problem in architecture where generics are either used where they shouldn't, or shouldn't be, and should.


If the above doesn't get you back on track, you should improve the question by providing a minimal, complete example code.

+2


source







All Articles