2009-05-12 8 views
1

J'ai le code suivant, où j'essaye de créer une collection générique pour les objets dans mon DAL (juste un exercice, pas réellement le code de production). Mon problème est que je veux utiliser le type transmis dans la méthode Read (qui fait partie d'une interface que les classes implémentent). Je ne peux pas créer un new T donc je n'ai pas une instance de l'objet avec lequel travailler, et je ne peux pas le déclarer comme type de base, car j'ai besoin de la méthode de lecture spécifiée par l'enfant de l'objet de base. Est-ce réellement possible ou est-ce que j'aboie le mauvais arbre?Chargement générique de la collection du type générique

public class ItemDictionary<T> where T : ILoadable, DataItem 
{ 

    public void Load() 
    { 
     using (IDataReader reader = SqlHelper.ExecuteReader(_connection, CommandType.StoredProcedure, _proc)) { 
      Read(reader); 
     } 
    } 

    bool Read(IDataReader reader) 
    { 
     while (reader.Read) 
     { 
      T item = default(T);   //Here be the problem 

      if (item.Read(reader)) 
      { 
       this.Add(item.Guid, item); 
      } 
     } 

     return true; 
    } 

} 

public class ExampleObject : DataItem, ILoadable 
{ 

    bool Read(IDataReader reader) 
    { 
     _var1 = reader.getString(0); 
     _var2 = reader.getString(1); 
     _var3 = reader.getString(2); 

     return true; 
    } 
} 

Répondre

3

Pouvez-vous pas un constructeur par défaut du type (s) retenu par la collection et ajouter la nouvelle() directive à laquelle T: directive?

public class ItemDictionary<T> where T : ILoadable, DataItem, new() 

puis: -

T item = new T(); 
+0

C'est exactement ce qui me manquait! Il a même travaillé dans VB.net :) – Pondidum

1

Il est pas clair pour moi pourquoi vous ne pouvez pas utiliser new T() (avec une contrainte appropriée sur T). Je ne comprends pas non plus pourquoi vous utilisez une implémentation d'interface explicite, et pourquoi votre interface ILoadable a une méthode appelée ILoadable, attention.

Le problème que vous ne pouvez pas toujours garantir d'avoir un constructeur sans paramètre dans le type d'objet? Si c'est le cas, vous aurez besoin de quelque chose pour créer des instances de T. Peut-être que vous avez réellement besoin de séparer T de son usine, peut-être avec une autre interface:

public interface IFactory<T> 
{ 
    // Roughly matching your current API 
    bool TryRead(IDataReader reader, out T); 

    // Simpler if you can just throw an exception on error 
    T Read(IDataReader reader); 
} 

alors vous pouvez juste passer une implémentation IFactory<T> dans votre constructeur ItemDictionary<T>.

+0

Désolé, nous avons converti ce formulaire vb.net avec un convertisseur de code en ligne ... – Pondidum

Questions connexes