locked
Is there a way to cast an IEnumerable object retrieved from reflection to an ArrayList or IEnumerable?

    Question

  •  

    Our system has 2 base classes, SingleEntity and NewPluralEntity. SingleEntity provides access to properties and methods related to manipulating data in a database table and NewPluralEntity is a generic base class that I inherit from to create strongly typed collections of single entities.

    Here is the declaration of our NewPluralEntity class:

    public abstract class NewPluralEntity<T> : ICollection<T>, IEnumerable<T>

    Here is a sample declaration of one of our inherited plural classes:

    public class Workplaces : NewPluralEntity<Workplace>

    My problem is that I have to use reflection to return an ArrayList (or some other type of collection that I may enumerate) that contains my Workplaces and I cannot find any way to get the object that is returned from reflection (PropertyInfo.GetValue()) to cast to an ArrayList (or other suitable type).

    For example, I have an Insured object. The Insured object has a Workplaces property. I need to use reflection to return an ArrayList that contains my Workplaces.

    Here is the code for my "GetNewPluralEntityPropertyUsingReflection" method:

    public ArrayList GetNewPluralEntityPropertyUsingReflection(string p_propertyName)  
    {  
      PropertyInfo myProperty = this.GetType().GetProperty(p_propertyName);  
      object res = myProperty.GetValue(this, null); //"this" is the fully loaded Insured object and "res" is a collection of workplaces although res is typed as an object due to the return type of GetValue being "object"
      return (ArrayList)res; //blows up...  
    }  
     

    When I invoke Insured.GetNewPluralEntityPropertyUsingReflection("Workplaces"); and step into the code and place a breakpoint on my "return (ArrayList)res;" statement I can see that the "res" variable has a value and that its base type is NewPluralEntity<Workplace>, with a count and several other properties that are in NewPluralEntity, but I cannot get the cast to ArrayList to succeed.

    Originally, I wanted the GetNewPluralEntityPropertyUsingReflection() method to return a NewPluralEntity<Workplace> but I found no way to cast an object to a generic type when I did not know the type at compile time (in my case the type is just a string "Workplaces"). If someone knows how to do return NewPluralEntity<Workplace> in this case that would be great too but ArrayList will do.

    Thanks in advance for any ideas.



    • Edited by kmccaa Tuesday, November 18, 2008 7:52 PM more details within code block comments.
    Tuesday, November 18, 2008 7:47 PM

Answers

  • Thanks to everyone for your thoughts. I did not get any notifications about all of the activity and I apologize for not keeping current.

    Anyhow, here is how I finally solved my problem.

    Basically, I decided, "If reflection is what is causing my problem maybe I can use reflection to solve my problem." So I decided to use the Invoke() method of the MethodInfo class to invoke my ToArrayList() method on my NewPluralEntity<T> base class.

    I am not sure if this is the fastest code in the world but it does work and it allows me to return the ArrayList even though the type of my generic if unknown.

        public ArrayList GetPluralEntityPropertyUsingReflection(string p_propertyName)
        {
          System.Reflection.PropertyInfo myProperty = this.GetType().GetProperty(p_propertyName);
          object res = myProperty.GetValue(this, null);
          Type t = res.GetType();
          System.Reflection.MethodInfo mi = t.GetMethod("ToArrayList");
          return (ArrayList)mi.Invoke(res, null);
        }

    Thanks for all of the replies. Next time I won't rely on being subscribed to threads and check them every day.

    • Marked as answer by kmccaa Thursday, December 11, 2008 2:08 PM
    Thursday, December 11, 2008 2:08 PM

All replies

  •  If possible, sounds like you need to add one more method to NewPluralEntity<>, GetArrayList(), which would return an ArrayList.

    Rudedog   =|^D
    Mark the best replies as answers. "Fooling computers since 1971."
    Tuesday, November 18, 2008 8:45 PM
  • Why do you have to use reflection to get a collection back?  If the property you are after is a Workplaces object, it is already a collection.

    But you can use IEnumerable for what I think you want...

            public IEnumerable GetNewPluralEntityPropertyUsingReflection(string p_propertyName)  
            {  
                PropertyInfo myProperty = this.GetType().GetProperty(p_propertyName);  
                object res = myProperty.GetValue(thisnull); //"this" is the fully loaded Insured object and "res" is a collection of workplaces although res is typed as an object due to the return type of GetValue being "object".    
                IEnumerable e = res as IEnumerable;  
                return e;  
            }  
     

    You would use it like so...
                Insured ins = new Insured();  
                ins.workplaces.Add(new Workplace());  
                IEnumerable npw = ins.GetNewPluralEntityPropertyUsingReflection("workplaces");  
                foreach (object o in npw)  
                    Console.WriteLine(o.GetType().ToString());  
     

    Your NewPluralEnty must imipliment the GetEnumerator().  If you are using an IEnumerable<T> object to backend the data inside of NewPluralEntity, then you can use code like this...

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()  
            {  
                return _lst.GetEnumerator();  
            }  
     

    Let me know if I'm missing your point.
    Les Potter, Xalnix Corporation, Yet Another C# Blog
    Tuesday, November 18, 2008 10:00 PM
  • Thanks to everyone for your thoughts. I did not get any notifications about all of the activity and I apologize for not keeping current.

    Anyhow, here is how I finally solved my problem.

    Basically, I decided, "If reflection is what is causing my problem maybe I can use reflection to solve my problem." So I decided to use the Invoke() method of the MethodInfo class to invoke my ToArrayList() method on my NewPluralEntity<T> base class.

    I am not sure if this is the fastest code in the world but it does work and it allows me to return the ArrayList even though the type of my generic if unknown.

        public ArrayList GetPluralEntityPropertyUsingReflection(string p_propertyName)
        {
          System.Reflection.PropertyInfo myProperty = this.GetType().GetProperty(p_propertyName);
          object res = myProperty.GetValue(this, null);
          Type t = res.GetType();
          System.Reflection.MethodInfo mi = t.GetMethod("ToArrayList");
          return (ArrayList)mi.Invoke(res, null);
        }

    Thanks for all of the replies. Next time I won't rely on being subscribed to threads and check them every day.

    • Marked as answer by kmccaa Thursday, December 11, 2008 2:08 PM
    Thursday, December 11, 2008 2:08 PM