Frage

Ich versuche, eine Hilfsmethode unter Verwendung von Generika zu implementieren (C # / 3.5) Ich habe eine schöne Struktur von Klassen, mit Basisklassen wie folgt:

public class SomeNiceObject : ObjectBase
{
  public string Field1{ get; set; }
}

public class CollectionBase<ObjectBase>()
{
  public bool ReadAllFromDatabase();
}

public class SomeNiceObjectCollection : CollectionBase<SomeNiceObject>
{

}

Und ich wünsche Sammlung unter Verwendung einer generische Methode retreive etwa so:

    public class DAL
    {

     public SomeNiceObjectCollection Read()
     {
      return ReadFromDB<SomeNiceObjectCollection>();
     }

     T ReadFromDB<T>() where T : CollectionBase<ObjectBase>, new()
     {
      T col = new T();
      col.ReadAllFromDatabase();
      return col;          
     }
   }

Dies gilt nicht bauen, mit

Error   66  The type 'SomeNiceObjectCollection' cannot be used as type parameter 'T' in the generic type or method 'ReadFromDB<T>'.   There is no implicit reference conversion from 'SomeNiceObjectCollection' to 'CollectionBase<ObjectBase>'.

Das SomeNiceObjectCollection-Objekt ist ein Collection, ein Collection genau zu sein. Also, wie kann ich diese Arbeit bekommen?

War es hilfreich?

Lösung

C # unterstützt nicht zwischen Listentypen Gießen (Kovarianz).

Ihre beste Wette, dieses Muster zu unterstützen wäre eine Schnittstelle für die ReadAllFromDatabase Methode einzuführen, so dass Sie nicht auf einer generische Auflistung setzen:

public class SomeNiceObject : ObjectBase
{
  public string Field1{ get; set; }
}

public interface IFromDatabase
{
  bool ReadAllFromDatabase();
}

public class CollectionBase<ObjectBase>() : IFromDatabase
{
  public bool ReadAllFromDatabase();
}

public class SomeNiceObjectCollection : CollectionBase<SomeNiceObject>
{

}

public class DAL
{

 public SomeNiceObjectCollection Read()
 {
  return ReadFromDB<SomeNiceObjectCollection>();
 }

 T ReadFromDB<T>() where T : IFromDatabase, new()
 {
  T col = new T();
  col.ReadAllFromDatabase();
  return col;          
 }
}

Andere Tipps

In C # 3.0 dies nicht möglich ist, aber mit C # und .NET 4.0 mit Kovarianz und Kontra, könnte dies möglich sein.

Denk darüber nach, Sie sind eine Sammlung unter einem abgeleitetes Objekt enthält, und versuchen, es vorübergehend als eine Sammlung des Basisobjekts zu behandeln. Wenn dies erlaubt wurde, Sie Basisobjekte in die Liste einfügen könnten, die nicht von dem abgeleiteten Objekt sein würde.

Hier ein Beispiel:

List<String> l = new List<String>();
List<Object> o = l;
l.Add(10); // 10 will be boxed to an Object, but it is not a String!
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top