обрабатывать элементы в общем списке / коллекциях с помощью Reflection - PullRequest
1 голос
/ 02 апреля 2009

У меня есть универсальный класс, который я использую Reflection для извлечения свойств типа универсального и поиска атрибута. Я повторюсь в каждом свойстве, чтобы сделать то же самое для каждого из своих свойств. Моя проблема, когда я прихожу к какому-либо свойству коллекции (свойство, которое является коллекцией) или свойству ICollection. Я не смогу привести значение, возвращенное из GetValue, к определенному типу (попытался преобразовать в IEnumerable, но не работает для универсальных IEnumerables).

Вот код, который поможет понять немного больше:

 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);

Объект User имеет правильные атрибуты

Ответы [ 4 ]

0 голосов
/ 19 апреля 2013

Последний ответ (Антон Гоголев) - один из лучших; например:

У меня была эта общая функция:

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

, который сам также возвращает общий список (List<[Unknown Model Type]> ...)

Я искал повсюду, чтобы получить от него единственный результат, но мне пришлось приводить его любым способом, прежде чем это сделать, и не было никакого способа определить пользовательский или любой другой класс модели (который я не знаю, какой именно быть) даже через генериков . Как только я увидел это, я сказал себе, я пробовал много способов, пусть тоже попробую, и я сделал это так:

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

и все заработало как надо !!

0 голосов
/ 02 апреля 2009

Вы можете попробовать привести тип коллекции свойства к фактическому типу коллекции?

вы делаете что-то вроде следующего:

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

Надеюсь, это поможет

0 голосов
/ 02 апреля 2009

Я выполняю приведение к IEnumerable, я пытался привести не тот объект, когда возникли проблемы.

0 голосов
/ 02 апреля 2009

Насколько я понимаю, не универсальный IEnumerable подойдет, так как вам все равно не нужна информация о типе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...