views:

612

answers:

3

I have a generic class that I am using Reflection to pull out the properties of the type of the generic and looking for an attribute. I am recursing into each property to do the same for each of their properties. My issue is when I come to some sort of collection property (property that is a collection) or ICollection property. I will not be able to cast the value returned from GetValue into a specific type (tried to cast into IEnumerable but does not work for generic IEnumerables).

Here is some code to help understand a little more:

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

The User object has the proper attributes

A: 

From what I understand, non-generic IEnumerable will do since you don't need the type information anyway.

Anton Gogolev
A: 

You could try casting the collection type of the property to the actual type of collection?

are you doing something like the following:

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

Hope this helps

w4ymo
I dont know the type.....the class that is using the reflection is a generic class
CSharpAtl
the article http://objectmix.com/csharp/151909-create-empty-list-type-name.html may help you here
w4ymo
A: 

I am doing the cast to IEnumerable, I was trying to cast the wrong object when I was having issues.

CSharpAtl