2009-04-02 6 views
1

J'ai une classe générique que j'utilise Reflection pour extraire les propriétés du type du générique et la recherche d'un attribut. Je suis récursif dans chaque propriété pour faire la même chose pour chacune de leurs propriétés. Mon problème est quand je viens à une sorte de propriété de collection (propriété qui est une collection) ou de propriété ICollection. Je ne serai pas en mesure de convertir la valeur renvoyée par GetValue en un type spécifique (j'ai essayé de transtyper dans IEnumerable mais ne fonctionne pas pour IEnumerables générique).traiter des éléments dans la liste générique/collections avec réflexion

Voici un code pour aider à comprendre un peu plus:

public class NotificationMessageProcessor<T> : INotificationProcessor<T> 
    { 
      IList<string> availableTags = new List<string>(); 

      public string ReplaceNotificationTags<T>(string message, T instance) 
      { 

      LoadTagValues(instance); 
      return ReplaceTags(message); 

      } 

      private string ReplaceTags(string message) 
      { 
      foreach (KeyValuePair<string, string> tagVal in tagValues) 
      { 
       message = message.Replace(string.Format("<{0}>", tagVal.Key),  tagVal.Value); 
      } 
      return message; 
      } 

      private void LoadTagValues(object val) 
      { 
       Type elementType = val.GetType(); 
       PropertyInfo[] typeProperties = elementType.GetProperties(); 
       foreach (PropertyInfo prop in typeProperties) 
       { 

       NotificationTag[] tags =  (NotificationTag[])prop.GetCustomAttributes(typeof(NotificationTag), false); 
       if (tags != null && tags.Length > 0) 
       { 
        string tagName = tags[0].TagName; 
        object propValue = prop.GetValue(val, null); 
        string propTypeString = prop.PropertyType.FullName; 
        tagName = prop.ReflectedType.Name + "." + tagName; 
        if (propValue != null) 
        { 
         tagValues.Add(tagName, propValue.ToString()); 
        } 

        if (propValue != null) 
        { 
         if (!prop.PropertyType.IsPrimitive) 
         { 
         LoadTagValues(propValue); 
         } 
        } 
       } 
       else 
       { 
        if (!prop.PropertyType.IsPrimitive) 
        { 
        object propValue = null; 

         if (prop.GetGetMethod().GetParameters().Count() == 0) 
         { 
          propValue = prop.GetValue(val, null); 
         } 
         else 
         { 
          //have a collection...need to process but do not know how many in collection.... 
           propValue = prop.GetValue(val, new object[] { 0 }); 

         } 
        if (propValue != null) 
        { 
         LoadTagValues(propValue); 
        } 
       } 
      } 
     } 
    } 




NotificationMessageProcessor<User> userProcessor = new NotificationMessageProcessor(); 
    userProcessor.ReplaceNotificationTags<User>(someMessage, instanceOfUser); 

L'objet utilisateur possède les attributs appropriés

+0

Certaines informations sur ce que vous voulez réellement faire seraient utiles - tout semble un peu étrange dans l'abstrait. –

+0

J'ai ajouté du code .... – CSharpAtl

+0

Je l'ai compris .... – CSharpAtl

Répondre

0

que je fais le casting à IEnumerable, je tentais de jeter le mauvais objet quand j'avais des problèmes.

0

D'après ce que je comprends, IEnumerable non générique fera puisque vous n'avez pas besoin l'information de type de toute façon.

0

Vous pouvez essayer de convertir le type de collection de la propriété en type de collection réel?

faites-vous quelque chose comme ce qui suit:

List<OfObject> myCollection = new List<OfObject>; 
myCollection = (List<OfObject>)objPropertyInfo.GetValue(List<ObjectHere>, Nothing); 

Hope this helps

+0

Je ne connais pas le type ..... la classe qui utilise la réflexion est une classe générique – CSharpAtl

+0

l'article http: // objectmix. com/csharp/151909-create-vide-list-type-name.html peut vous aider ici – w4ymo

0

Dernière réponse (Anton Gogolev) est l'un des meilleurs; par exemple:

J'ai eu cette fonction générique:

var fieldFetchedData = fieldQueryHandler.GetType().GetMethod("GetFilter").MakeGenericMethod(selectedParameter.ParameterType).Invoke(fieldQueryHandler,fieldParameters.ToArray()); 

qui se sont retournés également une liste générique (List<[Unknown Model Type]> ...)

Je regardais partout pour obtenir un seul résultat de celui-ci, mais je a dû le faire de toute façon avant de le faire, et il n'y avait aucun moyen de définir utilisateur ou toute autre classe de modèle (dont je ne sais pas lequel il devrait être), même à travers génériques. Une fois que je l'ai vu, je me suis dit, j'ai essayé plusieurs façons, laissez également donner ce un essai, et je l'ai fait comme ceci:

IEnumerator enumeratorFetchedData = ((IEnumerable) fieldFetchedData).GetEnumerator(); 
object obj = enumeratorFetchedData.MoveNext()? enumeratorFetchedData.Current:null; 

et cela a fonctionné comme il se doit !!

+0

sry pour mauvais anglais Jasse :) ce n'est pas ma langue et je l'apprends en parlant avec des gens autour du monde, pas de manière formelle –

Questions connexes