1

Im trying to build an application where the properties of the classes are set based on the values in som XML files.
Some of the classes has properties consisting of a list of of it's children. Due to the way i made this program, the properties has to be set via propertyinfo classes. My problem is that i have trouble with fetcing the list of children (ICollection in Derived2).
It must be cast to a generic list (ICollection OR HashSet), so i dont have to copy paste the same setChild method in each derived class. I've tried casting the GetValue return value to either ICollection, HashSet or IENumerable, none worked.
Maybe the solution could be to use another method of the PropertyInfo class?
A somewhat simplified code example code:

public interface Superclass
{}

public class Derived1 : Superclass {}

public class Derived2 : Superclass
{
    public Derived2()
    {
        PatientForloeb = new HashSet<Derived1>();
    }
    public virtual ICollection<Derived1>Derived1{ get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        List<Derived1> children = new List<Derived1>();
        children.Add(new Derived1());

        var parent = new Derived2();
        setChild(parent, children);
    }

    private static void setChild(Superclass parent, List<Derived1> children)
    {
        foreach (var child in children)
        {
            var p = (parent.GetType().GetProperty(child.GetType().Name)); // This is ugly, should be based on type not name, but it works for my app.
            var pi = p.GetValue(parent) as HashSet<Superclass>; ///////////<-------This gives null. This is the problem.
            pi.add(child);
        }
    }
}
bjar-bjar
  • 737
  • 1
  • 8
  • 21

1 Answers1

1
  1. Superclass doesn't have a property, so actually the p is null.
  2. Your property name is PatientForloeb not Derived1, maybe you are looking for this?

    var p = parent
            .GetType()
            .GetProperties()
            .First(x => x.PropertyType.GetGenericArguments()[0] == children.GetType().GetGenericArguments()[0]); 
    
  3. An HashSet<T> is an ICollection<T> but an ICollection<T> is not a HashSet.For example what would you expect to happen in this case:

    var list = new List<int>();
    var collection = list as ICollection<int>; // okey
    var set = collection as HashSet<int>; // null
    

But that's not the only problem, because ICollection<T> is not covariant. Also, you don't even need to use as operator just get the value and set it.

In fact you don't even need to get value of your property.if you look at it carefully, you are getting the value of the property of your parent.And then trying to set that value back to parent.Even if that works, nothing will change.You need:

p.SetValue(parent, children);
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • I made i copy and paste error, the property should be named the same as the value the collection holds. Please look at the edited post for the correct program. – bjar-bjar May 05 '14 at 09:16