Is it possible to have an array of Func's parameters

Is the following construction possible?

public IQueryable<T> AllWithFetch<TRelated>(IQueryable<T> existing, params Expression<Func<T, TRelated>>[] fetchExpressions) { return fetchExpressions.Aggregate(existing, (current, exp) => current.Fetch(exp)); } 

What then could be called so ...

 var allDetails = this.preGrantDetailRepository .AllWithFetch(this.preGrantDetailRepository.All, x => x.Case, x => x.CaseOwner) 

Basically, I am trying to include adding selection strategies for NHibernate to our abstract repository so that we can specify these strategies from our logical level without breaking the repository pattern. For example, if we changed from NHibernate to another ORM, we can provide the same repository methods, but implemented ORM for this.

The problem occurs when I try to connect to several functions in a param array.

So it works ...

 var allDetails = this.preGrantDetailRepository .AllWithFetch(this.preGrantDetailRepository.All, x => x.Case) 

But this fails: "type arguments cannot be deduced from their use" messge

 var allDetails = this.preGrantDetailRepository .AllWithFetch(this.preGrantDetailRepository.All, x => x.Case, x => x.CaseOwner) 

I am using .NET 3.5, repository template, Fluent NHibernate, SQL Server 2008

EDIT

I solved the problem using the Porges answers below, so I understood it. The problem was caused by improper use of TRelated. Here is the working method in the repository ...

 public IQueryable<T> AllWithFetch<T>(IQueryable<T> existing, params Expression<Func<T, Entity>>[] fetchExpressions) { return fetchExpressions.Aggregate(existing, (current, exp) => current.Fetch(exp)); } 

Now AllWithFetch is not TRelated, and I'm using the superclass of two objects (Case and CaseOwner) in Func.

Thanks for helping the guys

+4
source share
2 answers

The problem is your TRelated , it has nothing to do with params .

Try this for example:

 void DoSomething<T,U>(Func<T,U> f, Func<T,U> f2) { } void Main() { DoSomething((int x) => x + 1, (int x) => x + ""); } 

The compiler will conclude that T must be int , but it cannot infer a good type for U (I am not sure about the exact details, but usually it does not look for a type higher up the inheritance chain).

To make it work, you need to specify a superclass; in this case object :

 void Main() { DoSomething<int,object>((int x) => x + 1, (int x) => x + ""); } 

Thus, you will either need to specify a superclass for yourself (which looks like an object here), or just get rid of the TRelated parameter.

+4
source

You must have TRelated as the return value for each func. Do .Case and .CaseOwner have the same type? If not, you can use

 Func<T, object> 

instead (or any interface)

+2
source

Source: https://habr.com/ru/post/1396595/


All Articles