2010-10-12 8 views
2

J'ai le dépôt suivant que j'utilise pour les tests unitaires:C# Référentiel à l'aide Generics

public class MyTestRepository<T> 
{ 
    private List<T> entities = new List<T>(); 

    public IQueryable<T> Entities 
    { 
     get { return entities.AsQueryable(); } 
    } 

    public T New() 
    { 
     //return what here??? 
    } 

    public void Create(T entity) 
    { 
     entities.Add(entity); 
    } 

    public void Delete(T entity) 
    { 
     entities.Remove(entity); 
    } 
} 

Que dois-je retourner dans la nouvelle méthode()?

J'ai essayé:

public T New() 
    { 
     return (T) new Object(); 
    } 

Mais cela me donne l'exception suivante quand je lance mon test unitaire:

System.InvalidCastException: Unable to cast object of type 'System.Object' to type 'MyCustomDomainType'. 

Toute idée sur la façon de mettre en œuvre la nouvelle méthode()?

Répondre

10

Vous pouvez ajouter une contrainte pour le paramètre de type T:

public class MyTestRepository<T> where T : new() 

et return new T(); dans la méthode.

+0

Oui - cela fonctionne. Merci pour toutes les réponses, les gars. Je vais marquer cette réponse comme la bonne réponse parce qu'elle a obtenu le plus de votes. – thd

1

En supposant que le type T possède un constructeur public/par défaut, cela ne corrigerait-il pas l'exception?

public T New() 
{ 
    return new T(); 
} 
+1

Vous ne pouvez pas supposer, vous devez l'appliquer à l'aide de nouveaux() (comme d'autres l'ont mentionné). –

2

Vous devez modifier la définition de votre référentiel en ajoutant la nouvelle() contrainte, comme ceci:

public class MyTestRepository<T> where T : new() 
{ 
    ... 
} 

Cela limite les types qui peuvent être utilisés avec MyTestRepository à ceux qui ont un constructeur par défaut. Maintenant, dans votre New() méthode, vous pouvez faire:

public T New() 
{ 
    return new T(); 
} 
1

Cela ne fonctionnera pas car vous créez juste un objet, rien d'autre. Que diriez-vous la création de l'objet avec Activator:

return (T)Activator.CreateInstance(typeof(T)); 

Voir: http://msdn.microsoft.com/en-us/library/system.activator.aspx

+1

Bien que cela fonctionne, je préfère utiliser "où T: new()" et retourner un nouveau T() comme d'autres le suggèrent. – steinar

+0

Dans les cas comme celui-ci, toute utilisation de la réflexion est une indication que vous faites quelque chose de mal :-) (le plus souvent). –

+0

Comme mentionné, je suis d'accord que son n'est pas le chemin à parcourir puisque la condition où peut être utilisé pour s'assurer que le type peut être renouvelé. Dans d'autres cas, la réflexion serait valide. – steinar