使用Reflection在通用列表/集合中处理项目

时间:2009-04-02 14:58:46

标签: c# .net generics reflection

我有一个泛型类,我使用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 :(得分:0)

根据我的理解,非通用IEnumerable将会执行,因为您无论如何都不需要类型信息。

答案 1 :(得分:0)

您可以尝试将属性的集合类型转换为实际的集合类型吗?

你正在做如下的事情:

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

希望这有帮助

答案 2 :(得分:0)

我正在对IEnumerable进行强制转换,当我遇到问题时,我试图抛出错误的对象。

答案 3 :(得分:0)

最后答案(Anton Gogolev)是最好的之一;例如:

我有这个通用功能:

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;

它应该工作!!