title: Generic class used as constraint to generic method in C#?
body: <p>Am I doing something wrong or is it not possible to specify a generic class as a constraint to a generic method?</p>
  
  <p>I have been playing around with generics and <a href="http://developer.db4o.com/" rel="nofollow noreferrer">db4o</a> (open source object database) and am writing a test program (see code below) to store and retrieve some user defined generic collections.</p>
  
  <p>I am attempting to write a generic method (see <strong>GetCollectionFromDb</strong> below) to retrieve a specifically typed collection from the database.  Unfortunately, the code below returns a compiler generated error for the line:</p>
  
  <pre><code> MyCollection1 collection3 =
                    GetCollectionFromDb&lt;MyCollection1&gt;(Collection1Name);
  </code></pre>
  
  <p>The error message is:</p>
  
  <pre><code>The type 'GenericsTest.MyCollection1'cannot be used as type parameter 'T'
  in the generic type or method 'GenericsTest.Program.GetCollectionFromDb&lt;T&gt;(string)'.
  There is no implicit reference conversion from'GenericsTest.MyCollection1' to
  'GenericsTest.MyCollectionBase&lt;GenericsTest.MyCollection1&gt;'.
  </code></pre>
  
  <p>I would appreciate any suggestions as to what I may be doing wrong or how I could approach this differently to reach the deisred outcome.</p>
  
  <pre><code>using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Collections.ObjectModel;
  using Db4objects.Db4o;
  
   namespace GenericsTest 
      {
          public class Entity1
          {
              public string SomeProperty { get; set; }
          }
  
          public class Entity2
          {
              public string SomeProperty { get; set; }
          }
  
          public abstract class MyCollectionBase&lt;T&gt; : Collection&lt;T&gt;
          {
              protected MyCollectionBase() : this("") { }
  
              protected MyCollectionBase(string pCollectionName) 
              {
                  CollectionName = pCollectionName; 
              }
  
              public string CollectionName { get; set; }
          }
  
          public class MyCollection1 : MyCollectionBase&lt;Entity1&gt;
          {
              public MyCollection1(string pCollectionName) :
                                            base(pCollectionName) { }
  
              public void DoSomeWorkOnCollection1() {}
          }
  
          public class MyCollection2 : MyCollectionBase&lt;Entity2&gt;
          {
              public MyCollection2(string pCollectionName) :
                                            base(pCollectionName) { }
  
              public void DoSomeWorkOnCollection2() { }
          }
  
          public class Program
          {
              public static IObjectContainer db = null;
  
              public static void Main(string[] args)
              {
                  const string Collection1Name = "Entity1Collection";
                  const string Collection2Name = "Entity2Collection";
                  db = Db4oFactory.OpenFile("Test.db");
  
                  Entity1 entity1 = new Entity1();
                  MyCollection1 collection1 = new MyCollection1(Collection1Name);
                  collection1.Add(entity1);
                  db.Store(collection1);
  
                  Entity2 entity2 = new Entity2();
                  MyCollection2 collection2 = new MyCollection2(Collection2Name);
                  collection1.Add(entity1);
                  db.Store(collection2);
  
                  db.Commit();
                  db.Close();
                  db = Db4oFactory.OpenFile("Test.db");
  
                  MyCollection1 collection3 = 
                         GetCollectionFromDb&lt;MyCollection1&gt;(Collection1Name);
              }
  
              private static T GetCollectionFromDb&lt;T&gt;(string pCollectionName) 
                                                   where T : MyCollectionBase&lt;T&gt;
              {
                  IList&lt;T&gt; queryResult = db.Query((T c) =&gt; 
                                           c.CollectionName == pCollectionName);
                  if (queryResult.Count != 0) return queryResult[0];
  
                  return null;
              }
          } 
      }
  </code></pre>