title: Generic Type parameters for covariant params array
body: <p>I have an interface:</p>
  
  <pre><code>IReadOnlyList&lt;TEntity&gt; Execute&lt;TEntity&gt;(ILambdaQuery&lt;TEntity&gt; query, params ILambdaQuery&lt;TAssociatedEntity&gt;[] associations) where TAssociatedEntity : class, IAggregateRoot;
  </code></pre>
  
  <p>The interface is used to execute a query in a repository. Where TEntity is the type that you're expecting back and what you are querying and TAssociatedEntity are other queries that you'd like to run and that will be combined with the TEntity results that come back. Eg.</p>
  
  <pre><code>var courseQuery = LambdaQuery&lt;Course&gt;(c =&gt; c.Id == id);
  
  var studentsQuery = LambdaQuery&lt;Student&gt;(s =&gt; s.Courses.Any(c =&gt; c.id == id));
  
  var instructorsQuery = LambdaQuery&lt;Instructor&gt;(i =&gt; i.Courses.Any(c =&gt; c.id == id));
  
  var courses = this.repo.Execute&lt;Course&gt;(courseQuery, studentsQuery, instructorsQuery);
  </code></pre>
  
  <p>My question revolves around this parameter:</p>
  
  <pre><code>params ILambdaQuery&lt;TAssociatedEntity&gt;[] associations
  </code></pre>
  
  <p>So you can see from the example, the associations array could have different types of TAssociatedEntity. So how do I tell the compiler that?</p>
  
  <p>The interface above doesn't do the job. The compiler says that The type of namespace name 'TAssociatedEntity' could not be found...</p>
  
  <p>Is this inpossible? Any ideas out there?</p>
  
  <p><strong>EDIT - a request for more information:</strong></p>
  
  <p>The LambdaQuery class stores a where lambda expression clause and a associated entities to eager fetch. A multitude of these are passed to the repository Execute method which does:</p>
  
  <pre><code>    public IReadOnlyList&lt;TEntity&gt; Execute(ILinqQuery&lt;TEntity&gt; query, params ILinqQuery&lt;TAssociatedEntity&gt;[] associations)
      {
          var queryOver = this.GetSession().QueryOver&lt;TEntity&gt;().Where(query.WhereClause);
  
          query.FetchExpressions.ToList().ForEach(expression =&gt; queryOver = queryOver.Fetch(expression).Eager);
  
          var future = queryOver.Future&lt;TEntity&gt;();
  
          foreach (ILinqQuery&lt;TEntity&gt; association in associations)
          {
              var queryOverAssociation = this.GetSession().QueryOver&lt;TEntity&gt;().Where(association.WhereClause);
  
              association.FetchExpressions.ToList().ForEach(expression =&gt; queryOverAssociation = queryOverAssociation.Fetch(expression).Eager);
  
              queryOverAssociation.Future&lt;TEntity&gt;();
          }
  
          return this.ExecuteInTransaction(() =&gt; future.ToList());
      }
  </code></pre>
  
  <p>It runs the query and any associated queries as a batch and returns a requested TEntity with any bits filled in.</p>
  
  <p><strong>EDIT - more information</strong></p>
  
  <p>I'm not brilliant with nHibernate. But in my simple terms, anything that is executed with Future() is delayed until the ToList() is called. </p>
  
  <p>So if I had:</p>
  
  <pre><code>class Person
  {
     public string Id { get; set; }
     public List&lt;Arm&gt; Arms { get; set; }
     public List&lt;Leg&gt; Legs { get; set; }
  }
  
  class Arm
  {
     public string Id { get; set; }
     public List&lt;Hand&gt; Hands { get; set; }
  }
  
  class Leg
  {
     public string Id { get; set; }
     public List&lt;Foot&gt; Feet { get; set; }
  }
  </code></pre>
  
  <p>So if the Execute method was called for a TEntity of Person and a person had a collection of arms, each of which has a hand and a collection of legs, each of which has a foot, then we might have a called to Execute that looks like:</p>
  
  <pre><code>LambdaQuery&lt;Person&gt; personQuery = new LambdaQuery&lt;Person&gt;(t =&gt; t.Id == "123");
  LambdaQuery&lt;Arm&gt; armQuery = new LambdaQuery&lt;Arm&gt;(t =&gt; t.Person.Id == "123", t =&gt; t.Hands);
  
  Person person = personRepository.Execute(personQuery, armQuery);
  </code></pre>
  
  <p>Then it would send the following to the database in batch:</p>
  
  <pre><code>SELECT * FROM person WHERE personId = '123';
  SELECT * FROM arms a JOIN hands h ON h.armId = a.armId WHERE a.personId = "123"
  </code></pre>
  
  <p>And a (legless) Person object would be returned from the Execute method with:</p>
  
  <pre><code>Person
  ------
  { 
    Id : "123", 
    Arms : [ { Id : "ARM1", Hands : [ { Id : "HAND1" }, { Id : "HAND2" } ] } ], 
    Legs: null 
  }
  </code></pre>