I'm having trouble with passing in a predicate to another function. This predicate would have been passed in as a parameter that is trying 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 predicate parameter, on the call to GetList()
it keeps erroring, saying the call has some invalid arguments. The Get list call is:
public IEnumerable<TPart> GetList<TPart, TRecord>(Expression<Func<TRecord, bool>> predicate)
where TPart : ContentPart<TRecord>
where TRecord : ContentPartRecord
I been trying changing the parameter a bunch of different ways trying to get this to work but I haven't had any success. Maybe I'm not understanding why the compiler thinks that 'predicate' is different than what GetList()
is expecting.
EDIT: more information
ReportPart : ContentPart<ReportRecord>
ReportRecord : ContentPartRecord
ContentPart and ContentPartRecord are both 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();
}
Without a good, minimal, complete code example, it's impossible to know for sure what the best fix for your problem is, assuming one exists at all.
That said, variance problems generally come in two flavors: 1) what you're doing is truly wrong and the compiler is saving you, and 2) what you're doing is not provably correct, so you have to promise the compiler you know what you're doing.
If you're in the first category, then all is lost. You can't get this to work.
But if you're in the second category, you may be able to get your call to work by wrapping the original predicate in a new one that is compatible with the called method's requirements:
That said, while it's possible that there's some important reason for you writing the code this way, given the little bit of code you've shown so far, it's not really clear why you're trying to take the generic predicate and force it into the specific type.
Depending on what's really going on in the rest of the code, a pair of generic methods like this would work better where you either 1) go fully generic (i.e. don't force the type as
ReportRecord
in the call toGetList()
), or 2) you don't bother with the generic types at all (i.e. leave outTPart
andTRecord
from theBuildModel()
method).Example of 1):
Example of 2):
The mixing and matching, even if you can get it to work correctly, is often a sign that there's a more fundamental problem in the architecture, where generics are either being used where they shouldn't be, or are not being taken advantage as well as they should be.
If the above does not get you back on track, you really should improve the question by providing a minimal, complete code example.