0 votes

Pourquoi cette méthode générique exige-t-elle que T ait un constructeur public, sans paramètre ?

public void Getrecords(ref IList iList,T dataItem) 
{ 
  iList = Populate.GetList<dataItem>() // GetListis defined as GetList<T>
}

dataItem peut être mon objet de commande ou mon objet d'utilisateur, ce qui sera décidé au moment de l'exécution. Le type 'T' doit avoir un constructeur public sans paramètre afin de l'utiliser comme paramètre 'T' dans le type générique.

4voto

David Alpert Points 2305

Votre question révisée transmet dataItem comme un objet de type T et essaie ensuite de l'utiliser comme argument de type à GetList(). Peut-être que vous passez dataItem uniquement comme un moyen de spécifier T ?

Si c'est le cas, vous pourriez vouloir quelque chose comme ça :

public IList<T> GetRecords<T>() {
  return Populate.GetList<T>();
}

Alors vous appelez ça comme ça :

IList<int> result = GetRecords<int>();

3voto

James Curran Points 55356
public void GetRecords<T>(ref IList<T> iList, T dataitem)
{
}

Que cherchez-vous de plus ?

A la question révisée :

 iList = Populate.GetList<dataItem>()

"dataitem" est une variable. Vous voulez y spécifier un type :

 iList = Populate.GetList<T>()

Le type "T" doit avoir une fonction publique paramètre public l'utiliser en tant que paramètre 'T' dans la méthode générique type GetList:new()

Cela signifie que lorsque vous avez défini Populate.GetList(), vous l'avez déclaré comme ceci :

IList<T> GetList<T>() where T: new() 
{...}

Cela indique au compilateur que GetList ne peut utiliser que les types qui ont un constructeur public sans paramètre. Si vous utilisez T pour créer une méthode GetList dans GetRecords (T fait référence à différents types ici), vous devez lui imposer la même limitation :

public void GetRecords<T>(ref IList<T> iList, T dataitem) where T: new() 
{
   iList = Populate.GetList<T>();
}

1voto

Marc Gravell Points 482669

Le problème de l'exigence d'un constructeur public sans paramètre ne peut venir que du fait que Populate.GetList l'exige - c'est-à-dire qu'il a la contrainte "T : new()". Pour résoudre ce problème, il suffit d'ajouter la même contrainte à votre méthode.

En fait, je doute que ref est une bonne stratégie ici. En poussant un peu, out pourrait faire l'affaire (puisque vous ne lisez pas la valeur), mais une option beaucoup plus simple (et plus attendue) est une valeur de retour :

public IList<T> GetRecords<T>(T dataItem) where T : new()
{  // MG: what does dataItem do here???
  return Populate.GetList<T>();
}

Bien sûr, à ce moment-là, l'appelant pourrait aussi bien appeler Populate.GetList directement !

Je pense que vous pouvez également supprimer dataItem... mais la question n'est pas tout à fait claire.

Si vous ne voulez pas qu'il soit générique (et que dataItem est l'objet du modèle), vous pouvez le faire via MakeGenericMethod :

public static IList GetRecords(object dataItem) 
{
    Type type = dataItem.GetType();
    return (IList) typeof(Populate).GetMethod("GetList")
        .MakeGenericMethod(type).Invoke(null,null);
}

-1voto

Patrick Desjardins Points 51478

Vous pouvez utiliser Generic avec < T > qui acceptera le type en cours d'exécution comme vous le souhaitez.

-1voto

Ryan Lanciaux Points 4835
Getrecords<T> ...

Vous devriez y trouver toutes les informations plus détaillées dont vous avez besoin. http://msdn.microsoft.com/en-us/library/twcad0zb (VS.80).aspx

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X