0

I have 2 classes. ClassA has some objects of ClassB called Field01, Field02, ... Class A also has a list of ClassB items.

I know the name of the ClassB items and want to fill the ClassB items with the values from the list.

Example code:

public class ClassA
{
    public ClassB Field01 {get;set;}
    public ClassB Field02 {get;set;}
    //...

    List<ClassB> myItems;

    public void FillItems()
    {
        foreach(var item in MyItems)
        {
           // what I want in hardcode:
           Field01.ValueA = MyItems[0].ValueA;
           Field01.ValueB = MyItems[0].ValueB;
           Field02.ValueA = MyItems[1].ValueA;
           // ...
        }
    }
}

public class ClassB 
{
    public string ValueA {get;set;}
    public string ValueB {get;set;}
}

In my case I'll have a counting variable which will create the Field01, Field02, Field03, ... names depending on how many items are in my List (there are always enough ClassB fields in ClassA to fill)

I know i can get the PropertyInfo of my ClassB items via name, but I don't know you I can access the ClassB attributes ValueA and ValueB

// If ClassB was just a string or object this would work
Type myType = typeof(ClassA);
PropertyInfo myPropInfo = myType.GetProperty("Field01");
myPropInfo.SetValue(this, "Hello", null);
Aiko West
  • 791
  • 1
  • 10
  • 30
  • Did you write an extra foreach loop in your example code? – Sweeper Jan 15 '20 at 06:51
  • what do you mean by "extra" – Aiko West Jan 15 '20 at 06:55
  • https://stackoverflow.com/questions/34628996/how-do-i-get-the-properties-from-a-subclass-when-i-have-the-class-but-subclass-n – Salah Akbari Jan 15 '20 at 06:56
  • @K.Dexter The foreach loop in the example code seems to be redundant, no? Surely you don't want to set every field many times with the same value? You are not using `item` anyway. – Sweeper Jan 15 '20 at 07:04
  • @Sweeper ah I now what you mean... the hardcode code belongs above the foreach... in the foreach loop, the fieldnames are generated and each item adresses one field :) I am testing your answer right now – Aiko West Jan 15 '20 at 07:17
  • On second thought: this is quite a weird thing that you are doing. What are you trying to do? Are you trying to create deep copies of `ClassB` that are in the list? Why do you have numbered properties? Why not another list? – Sweeper Jan 15 '20 at 07:39
  • currently this is a temporary solution. I am getting the filled list from my service, but for mapping those items to a data grid, I need the filled fields – Aiko West Jan 15 '20 at 07:42

1 Answers1

1

Since you know the declaring type of the properties is ClassB, you can get the PropertyInfo of ValueA and ValueB. Then, you need to get the value of FieldXX (not set it!) and set ValueA and ValueB.

We are going to be dealing with multiple Type, PropertyInfo and object objects, so you should name your variables appropriately, instead of just myPropInfo or myType.

for (int i = 0 ; i < MyItems.Count ; i++) {
    var classAType = typeof(ClassA);
    var classBType = typeof(ClassB);
    var fieldInfo = classAType.GetProperty("Field" + $"{i}".PadLeft(2, '0'));
    var fieldValue = fieldInfo.GetValue(this);
    var valueAInfo = classBType.GetProperty(nameof(ClassB.ValueA));
    var valueBInfo = classBType.GetProperty(nameof(ClassB.ValueB));
    valueAInfo.SetValue(fieldValue, valueAInfo.GetValue(MyItems[i]));
    valueBInfo.SetValue(fieldValue, valueBInfo.GetValue(MyItems[i]));
}
Aiko West
  • 791
  • 1
  • 10
  • 30
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • ok this works so far :) but only if I instantiate my ClassB objects in ClassA `public ClassB Field01 {get;set;} = new ClassB();` – Aiko West Jan 15 '20 at 07:22
  • @K.Dexter Of course you need to instantiate them! Otherwise you'd get a [NRE](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it). – Sweeper Jan 15 '20 at 07:24
  • is there a way to instantiate them in the loop ? – Aiko West Jan 15 '20 at 07:24
  • 1
    @K.Dexter Instead of `var fieldValue = fieldInfo.GetValue(this);`, you write `var fieldValue = new ClassB();` and `fieldInfo.SetValue(this, fieldValue);` – Sweeper Jan 15 '20 at 07:26