2009-05-27 10 views
13

J'ai une question sur comment est-il possible (si possible :) d'utiliser une référence de type retournée par Type.GetType() pour, par exemple, créer IList de ce type?en utilisant le type retourné par Type.GetType() dans C#

voici un exemple de code:

Type customer = Type.GetType("myapp.Customer"); 
IList<customer> customerList = new List<customer>(); // got an error here =[ 

Merci à l'avance vous!

+0

IList est une interface, vous ne pouvez pas nouveau il. Vous devez créer un nouveau type qui implémente IList tel que Liste . –

Répondre

21

Quelque chose comme ceci:

Type listType = typeof(List<>).MakeGenericType(customer); 
IList customerList = (IList)Activator.CreateInstance(listType); 

Bien sûr, vous ne pouvez pas déclarer comme

IList<customer> 

parce qu'il est pas défini au moment de la compilation. Mais List<T> implémente IList, vous pouvez donc l'utiliser.

+3

Oui, parce que ce n'est pas défini au moment de la compilation, il n'y a pas grand intérêt à utiliser un List <> générique - vous pouvez aussi bien utiliser un conteneur non générique tel que ArrayList. – Grokys

+0

En fait, vous devriez convertir le résultat d'Activator.CreateInstance en IList, puisqu'il renvoie un objet ... –

+1

@Thomas: merci, corrigez-le. @Groky: Cela dépend. En utilisant la liste générique, vous obtenez des vérifications de type à l'exécution lors de l'ajout d'éléments. Ou vous devez l'assigner à un champ que vous connaissez (par un contexte) qu'il est du même type. –

0

La solution à votre problème est déjà fournie par Stefan.

La raison pour laquelle vous ne pouvez pas faire IList<customer> est que vous ne pouvez pas mélanger les types de compilation et d'exécution de cette manière. Une allusion quand je tente de raisonner sur quelque chose comme ceci est: comment l'intellisense peut-elle comprendre quels membres elle doit montrer. Dans votre exemple, cela ne peut être résolu qu'à l'exécution.

La réponse de Stefan peut être utilisée. Cependant, je pense que cela n'aide pas dans votre problème sous-jacent, parce que cela ne vous donne pas d'intellisense. Je pense donc que vous n'avez aucun avantage à n'utiliser qu'une liste non générique.

+0

Comme Stefan l'a souligné dans les commentaires pour sa réponse il y a toujours des advandages, tels que la liste générique empêchant le code d'ajouter des objets de types différents à la liste. Vous perdez quand même l'intellisense. –

2

J'ai récemment fait face à ce problem..I réaliser c'est une vieille question, mais pensé que quelqu'un pourrait trouver utile la solution que j'ai trouvé (en utilisant net 4,0). Ce est la configuration que j'ai eu:

public interface ISomeInterface{ 
    String GetEntityType{ get; } 
} 

public abstract class BaseClass : ISomeInterface{ 
    public String GetEntityType { 
      get{ return this.GetType().ToString(); } 
    } 
} 

public class ChildA : BaseClass { } 

public class ChildB : BaseClass { } 

Ce que je faisais était de créer une méthode de fabrication:

public static dynamic GetRealType { ISomeInterface param } { 
    return Activator.CreateInstance("dllname", param.GetEntityType); 
} 

Création de l'objet comme un type dynamique est ce qui a résolu le problème pour moi. Je jugeai le type en ayant une méthode:

public void DoSomething<T>(T param){ 

    IList<T> list = somecode... 
} 

cela m'a permis de faire un appel à la méthode et laisser .net déduire le type

public void myMethod(ISomeInterface param) { 
    dynamic value = Factory.GetRealType (param); 
    DoSomething(value); 
} 

espoir que je ne l'ai pas tout confus et il aide en fait, aussi, désolé pour le mur du texte

Questions connexes