简体   繁体   中英

C# Accessing a property of nested classes in a loop

I am trying to access a property of a nested class through reflection while looping but cannot find a way to do so. I am much more familiar with JavaScript than C# so I will explain my problem in JS terms and show what I have tried with C#.

What I want to accomplish with working JavaScript:

var myObj = {
  prop1: {p1: 0, p2: 1, p3: 2},
  prop2: {p1: 0, p2: 2, p3: 4},
  prop3: {p1: 0, p2: 4, p3: 8}
};

console.log(myObj.prop2.p2); //2

for( prop in myObj ) {
  //Since I know the inner properties are the same
  myObj[prop].p1++;
  myObj[prop].p2++;
  myObj[prop].p3++;
}

console.log(myObj.prop2.p2); //3

Here is what I have tried in C#, but with no luck:

class myObj
{
    public class myPropObj
    {
        public int p1 {get; set;}
        public int p2 {get; set;}
        public int p3 {get; set;}
        public myPropObj(int one, int two, int three)
        {
            p1 = one;
            p2 = two;
            p3 = three;
        }
    }
    public myPropObj prop1 = new myPropObj(0, 1, 2);
    public myPropObj prop2 = new myPropObj(0, 2, 4);
    public myPropObj prop3 = new myPropObj(0, 4, 8);
}
--------------------------------------------------------------
//Not working
myObj myObject = new myObj();

Console.WriteLine(myObject.prop2.p2);  //2

foreach( var prop in typeof(myObject).GetProperties() )
{
    //I am thinking I need to cast it to the same type as nested class, but unsure how to do this
    ((myObject.myPropObj)prop).p1++;
    ((myObject.myPropObj)prop).p2++;
    ((myObject.myPropObj)prop).p3++;
}

Console.WriteLine(myObj.prop2.p2);  //3

Thank you very much for taking the time to help me.

Note : As both Eric and I have pointed out, taking such an approach is not the idiomatic way of solving such problems. Without context, it's difficult to suggest alternative solutions, but... beware. Reflection is generally best avoided unless you have a real need for it.

So a number of issues.

1) C# guidelines mandate CapitalCamelCase for class names. I'll be doing that in this answer.

2) public MyPropObj prop1 = new MyPropObj(0, 1, 2);

this is not a property. This is a field, so it's not picked up by GetProperties() . C# guidelines recommend against public fields, so the best approach is to swap to public properties instead:

public MyPropObj prop1 { get; set; } = new MyPropObj(0, 1, 2);

and so on...

3) Calling GetProperties on a Type returns an array of PropertyInfo . These in turn expose a method GetValue , which can be invoked to get the value of the property:

var obj = prop.GetValue(myObject); //this is always of type Object
var propObj = (MyObj.MyPropObj)obj; //so we need to cast it

Now we can take that propObj and

propObj.p1++;
propObj.p2++;
propObj.p3++;

as normal. You don't need reflection for this part.

Putting this all together:

void Main()
{
    MyObj myObject = new MyObj();
    Console.WriteLine(myObject.prop2.p2);  //2
    foreach (var prop in typeof(MyObj).GetProperties())
    {
        var propObj = (MyObj.MyPropObj)prop.GetValue(myObject);
        propObj.p1++;
        propObj.p2++;
        propObj.p3++;
    }
    Console.WriteLine(myObject.prop2.p2);  //3
}

class MyObj
{
    public class MyPropObj
    {
        public int p1 { get; set; }
        public int p2 { get; set; }
        public int p3 { get; set; }

        public MyPropObj(int one, int two, int three)
        {
            p1 = one;
            p2 = two;
            p3 = three;
        }
    }

    public MyPropObj prop1 { get; set; } = new MyPropObj(0, 1, 2);
    public MyPropObj prop2 { get; set; } = new MyPropObj(0, 2, 4);
    public MyPropObj prop3 { get; set; } = new MyPropObj(0, 4, 8);
}

However , this is not idiomatic C#, and the number of times you might choose to attack a problem with (slow) reflection are few and far between. There are almost always better ways to crack the nut.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM