C# 在循环中访问嵌套 类 的 属性
C# Accessing a property of nested classes in a loop
我试图在循环时通过反射访问嵌套 class 的 属性,但找不到这样做的方法。
我对 JavaScript 比 C# 熟悉得多,所以我将用 JS 术语解释我的问题并展示我用 C# 尝试过的内容。
我想通过工作完成什么 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
这是我在 C# 中尝试过的方法,但没有成功:
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
非常感谢您抽出时间来帮助我。
注意:正如埃里克和我所指出的,采用这种方法并不是解决此类问题的惯用方法。没有上下文,很难提出替代解决方案,但是......要小心。通常最好避免反射,除非您确实需要反射。
这么多问题。
1) C# 准则要求 CapitalCamelCase
用于 class 名称。我将在这个答案中这样做。
2) public MyPropObj prop1 = new MyPropObj(0, 1, 2);
这不是 属性。这是一个字段,因此未被 GetProperties()
拾取。 C# 指南建议不要使用 public 字段,因此最好的方法是改为使用 public 属性:
public MyPropObj prop1 { get; set; } = new MyPropObj(0, 1, 2);
等等...
3) 在 Type
returns 数组 PropertyInfo
上调用 GetProperties
。这些依次公开了一个方法 GetValue
,可以调用该方法来获取 属性:
的值
var obj = prop.GetValue(myObject); //this is always of type Object
var propObj = (MyObj.MyPropObj)obj; //so we need to cast it
现在我们可以取 propObj
和
propObj.p1++;
propObj.p2++;
propObj.p3++;
正常。这部分不需要反思。
综合起来:
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);
}
但是,这不是惯用的 C#,您可能会选择使用(慢)反射来攻击问题的次数少之又少。几乎总是有更好的方法来解决问题。
我试图在循环时通过反射访问嵌套 class 的 属性,但找不到这样做的方法。 我对 JavaScript 比 C# 熟悉得多,所以我将用 JS 术语解释我的问题并展示我用 C# 尝试过的内容。
我想通过工作完成什么 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
这是我在 C# 中尝试过的方法,但没有成功:
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
非常感谢您抽出时间来帮助我。
注意:正如埃里克和我所指出的,采用这种方法并不是解决此类问题的惯用方法。没有上下文,很难提出替代解决方案,但是......要小心。通常最好避免反射,除非您确实需要反射。
这么多问题。
1) C# 准则要求 CapitalCamelCase
用于 class 名称。我将在这个答案中这样做。
2) public MyPropObj prop1 = new MyPropObj(0, 1, 2);
这不是 属性。这是一个字段,因此未被 GetProperties()
拾取。 C# 指南建议不要使用 public 字段,因此最好的方法是改为使用 public 属性:
public MyPropObj prop1 { get; set; } = new MyPropObj(0, 1, 2);
等等...
3) 在 Type
returns 数组 PropertyInfo
上调用 GetProperties
。这些依次公开了一个方法 GetValue
,可以调用该方法来获取 属性:
var obj = prop.GetValue(myObject); //this is always of type Object
var propObj = (MyObj.MyPropObj)obj; //so we need to cast it
现在我们可以取 propObj
和
propObj.p1++;
propObj.p2++;
propObj.p3++;
正常。这部分不需要反思。
综合起来:
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);
}
但是,这不是惯用的 C#,您可能会选择使用(慢)反射来攻击问题的次数少之又少。几乎总是有更好的方法来解决问题。