2008-10-30 5 views
1
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 objet utilisateur qui sera décidé à l'exécution temps.Le ne fonctionne pas au-dessus car il me donne cette erreur Le type « T » doit avoir un constructeur parameterless public afin de l'utiliser comme paramètre 'T' dans le type génériquePourquoi cette méthode générique nécessite-t-elle que T ait un constructeur public sans paramètre?

+0

vous êtes question est très vague et difficile à comprendre .. . Qu'essayez-vous de faire? –

+0

a formaté ma question –

+1

Pourquoi ce type est-il rejeté pour simplement poser une question? –

Répondre

-1

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

5
public void GetRecords<T>(ref IList<T> iList, T dataitem) 
{ 
} 

Que recherchez-vous?

A la question révisée:

iList = Populate.GetList<dataItem>() 

"dataitem" est une variable. Vous souhaitez spécifier un type là:

iList = Populate.GetList<T>() 

Le type 'T' doit avoir un constructeur public parameterless pour l'utiliser comme paramètre 'T' dans le Type GetList générique: nouvelle()

cela revient à dire que, vous déclarez comme Populate.GetList() lors de la définition suivante:

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

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

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

Merci James pour que des informations détaillées –

4

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

Si oui, le vous voudrez peut-être quelque chose comme ceci:

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

Ensuite, vous appelez ça comme ceci:

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

j'ai essayé et j'obtenir ce le type « T » doit avoir un constructeur parameterless public afin de l'utiliser comme paramètre « T » dans le type générique GetList : nouvelle() –

+0

Si vous devez être en mesure d'en créer un nouveau, spécifiez T: objet –

+0

Vous pouvez également utiliser la valeur par défaut (T) pour créer une nouvelle instance. –

2

Le problème avec exigeant public, constructeur parameterless ne peut être parce que Populate .GetList l'exige - ie a la contrainte "T: new()". Pour résoudre ce problème, ajoutez simplement la même contrainte à votre méthode.

En fait, je doute que ref est une bonne stratégie ici. Lors d'une poussée, out peut faire (puisque vous ne lisez pas la valeur), mais beaucoup plus simple (et plus attendue) option 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 Il suffit d'appeler le Populate.GetList directement!

Je suppose que vous pouvez également supprimer dataItem ... mais la question ne vous le permet pas.

Si vous ne souhaitez pas être générique (et DataItem est l'objet de 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); 
} 
+0

MG: Si j'ai un objet de commande, la liste sera une collection d'objets de commande et évitera de construire ma propre collection fortement typée héritant de la base de la collection et passant en boucle dans un ensemble de données et construisant la collection pour que je puisse passer la collection personnalisée au lieu d'un ensemble de données –