2009-09-11 9 views
1

Je suis en train de mettre en œuvre une méthode d'assistance en utilisant les médicaments génériques (C#/3.5) J'ai une belle structure de classes, avec des classes de base comme ceci:Utilisation des objets de base comme paramètres dans une fonction générique

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

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

public class SomeNiceObjectCollection : CollectionBase<SomeNiceObject> 
{ 

} 

Et je tiens à retreive collection à l'aide d'une méthode générique comme ceci:

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;   
    } 
    } 

Cela ne construit pas, avec

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>'. 

L'objet SomeNiceObjectCollection EST une CollectionBase, une CollectionBase pour être exacte. Alors, comment puis-je faire fonctionner ça?

Répondre

2

C# ne prend pas en charge la coulée entre les types de liste (de covariance).

Votre meilleur pari pour soutenir ce modèle serait d'introduire une interface pour la méthode ReadAllFromDatabase de sorte que vous ne comptez pas sur une collection générique:

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;   
} 
} 
+0

Excellent.CollectionBase mis en œuvre allready une interface que je avais besoin, je a changé le ReadFromDB . Merci! – edosoft

2

En C# 3.0 ce n'est pas possible, mais avec C# et .NET 4.0 avec covariance et contravariance, cela pourrait être possible. Pensez-y, vous prenez une collection contenant un objet dérivé et vous essayez de la traiter temporairement comme une collection de l'objet de base. Si cela était autorisé, vous pourriez insérer des objets de base dans la liste, qui ne seraient pas de l'objet dérivé.

Voici un exemple:

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! 
Questions connexes