Voir j’ai une situation comme celle-ci …
object myRoledata = List() --> (some list or Ienumerable type)
Maintenant, j’ai une méthode générique qui crée un object XML à partir de List
– quelque chose comme ça ..
public ssortingng GetXML(object listdata) { List objLists = (List)Convert.ChangeType(listData, typeof(List)); foreach(var obj in listdata) { //logic to create xml } }
Maintenant, pour exécuter cette méthode, je dois faire comme ceci:
ssortingng xml = GetXML(myRoledata);
Maintenant, je ne sais pas quel Type
peut venir à moi pour être passé à la méthode GetXML
. J’ai une méthode qui appellera GetXML
pour différents Type
par exemple Roles
, Users
etc.
Maintenant, je peux obtenir le Type
dans la List
comme ceci
Type genericType = obj.GetType().GetGenericArguments()[0];
mais ne peut pas passer comme ça
ssortingng xml = GetXML(myRoledata);
Y at-il de toute façon dans lequel je peux passer n’importe quel genericTypes
à la méthode GetXML
?
C’est un problème que vous voulez probablement éviter de résoudre. Il est possible, par reflection, d’appeler des méthodes de manière dynamic sans les résoudre statiquement – mais cela annule en quelque sorte le point entier des annotations de type.
Soit faire ceci:
public ssortingng GetXML(IEnumerable listdata) { foreach(object obj in listdata) //logic to create xml }
… que vous pouvez maintenant appeler avec n’importe quel IEnumerable
, ou l’écrire de manière “moderne” en tant que:
public ssortingng GetXML(IEnumerable
… que vous pouvez appeler avec n’importe quel IEnumerable
via GetXML(someEnumerable.Cast
et en C # 4.0, même directement par covariance.
Si vous avez besoin du type d’exécution d’un élément, vous pouvez l’obtenir en utilisant .GetType()
sur chaque élément, ou vous pouvez simplement le transmettre en tant que paramètre (et fournir un remplacement pour la compatibilité avec les .GetType()
):
public ssortingng GetXML(Type elementType, IEnumerable
Incidemment, si vous construisez du XML, une chaîne est probablement un choix de type de retour moins robuste: si possible, vous pouvez travailler avec quelque chose comme un XElement
– et obtenir la garantie xml- XElement
de démarrer.
Pour ce faire, vous devez utiliser la reflection.
typeof(SomeClass).GetMethod("GetXML").MakeGenericMethod(genericType) .Invoke(inst, new object[] {myRoleData});
où inst
est null
s’il s’agit d’une méthode statique, this
pour l’instance actuelle (dans ce cas, vous pouvez également utiliser GetType()
place de typeof(SomeClass)
), ou l’object cible sinon.
Puisque vous convertissez votre paramètre listdata sous la forme d’une liste
public ssortingng GetXML(List listdata)
De cette façon, vous n’avez pas à utiliser la reflection pour obtenir les arguments génériques.
EDIT: Je vois que vous devez être capable d’accepter les collections IEnumerable, et pas seulement les listes. Alors, envisagez de changer votre signature de méthode pour
public ssortingng GetXML(IEnumerable listdata)
Je ne connais pas votre situation, mais est-il possible de réécrire votre fonction en tant que:
public ssortingng GetXML(IEnumerable listdata) { foreach(var obj in listdata) { //logic to create xml } }
Ensuite, il peut être appelé comme:
List myList; GetXML(myList);
Vous pouvez append des parameters de type aussi loin que nécessaire pour le prendre en charge, jusqu’à ce que vous arriviez à un endroit qui connaît le type de solide.
Vous avez la bonne idée, mais vous utilisez la mauvaise méthode. Jetez un coup d’œil à Type.MakeGenericType ou MethodInfo.MakeGenericMethod. Cela prendra quelques lignes de plus que votre exemple, mais sa résolution devrait être simple.
GetGenericArguments () peut être utilisé pour obtenir le type de rôle à partir d’une liste. C’est le chemin différent.
Btw: On dirait que vous implémentez une sorte de sérialisation XML. Assurez-vous de vérifier les classes existantes avant de réinventer la roue. 😉