如何从主类中循环子类属性?

时间:2011-05-28 14:00:45

标签: c#

如何从主类中循环子类属性?

public class GroupA
{
  public string FullName = "", BirthDay = "";
}
public class GroupB
{
  public string Email = "";
}
public class GroupC
{
  public string Phone;
}

public class MainGroup
{
  public GroupA GroupA;
  public GroupB GroupB;
  public GroupC GroupC;
}


    protected void Page_Load(object sender, EventArgs e)
    {

      GroupA  NewGroupA = new GroupA();
              NewGroupA.FullName="TEST MASTER";
              NewGroupA.BirthDay="02/20/1984";
      GroupB  NewGroupB = new GroupB();
              NewGroupB.Email="noreply@test.com"; 
      GroupC  NewGroupC=new GroupC();
              NewGroupC.Phone="555 123 4567";

      //Assign new class instances to the main class
      MainGroup NewMainGroup= new MainGroup();
                NewMainGroup.GroupA=NewGroupA;
                NewMainGroup.GroupB=NewGroupB;                 
                NewMainGroup.GroupC=NewGroupC;

      //Loop through the main class

      foreach (var Group in typeof(MainGroup).GetFields())
      {
        Response.Write("<BR>MainGroupName=  " + Group.Name + " Value=  " + Group.GetValue(NewMainGroup).ToString());
        //PROBLEM IS HERE. Can't loop through the subclass We need to display the GroupA, GroupB, GroupC below.
        foreach (var SubGroup in Group)
        {
          Response.Write("<BR>");
        }


      }
}

3 个答案:

答案 0 :(得分:3)

如果我理解你的问题,我认为这段代码就是你的答案:

foreach (var group in NewMainGroup.GetType().GetFields())
{
    var groupInstance = group.GetValue(NewMainGroup);
    foreach (var subGroup in groupInstance.GetType().GetFields())
    {
        Response.Write("<br />" + subGroup.Name + " = " + subGroup.GetValue(groupInstance));
    }
}

答案 1 :(得分:1)

您应该存储对组变量的引用(而不仅仅是类型)。所以,如果你采取你的代码并做这样的事情:

foreach (var GroupType in typeof(MainGroup).GetFields())
{
    object Group = GroupType.GetValue(NewMainGroup);
    Response.Write("<BR>MainGroupName=  " + GroupType.Name + " Value=  " + Group.ToString());
    foreach(var SubGroupType in Group.GetType().GetFields()) {
        object SubGroup = SubGroupType.GetValue(Group);
        Response.Write("<BR>SubGroupName= " + SubGroupType.Name + " Value= " + SubGroup.ToString());
    }
}

没有测试过,但我认为这应该是关于工作的。至少让你开始。

哦,顺便说一下,我想我有更好的方法,试试这个:

public Dictionary<string, object> GetObjectFields(object obj) {
    var dict = new Dictionary<string, object>();
    var t = obj.GetType();
    foreach(var f in t.GetFields()) {
        dict[f.Name] = f.GetValue(obj);
    }
    return dict;
}

然后你可以这样做:

var groupVars = GetObjectFields(NewMainGroup);
foreach(var gv in groupVars) {
    Response.Write(<BR>MainGroupName=  " + gv.Key + " Value=  " + gv.Value.ToString());
    var subGroupVars = GetObjectFields(gv.Value);
    foreach(var sgv in subGroupVars) {
        Response.Write(<BR>SubGroupName=  " + sgv.Key + " Value=  " + sgv.Value.ToString());
    }
}

答案 2 :(得分:1)

首先,GroupA,GroupB和GroupC不是MainGroup的子类。 您正在使用合成并拥有GroupA,GroupB和GroupC类型的成员。

当您已经知道自己的类型时,不确定为什么要重新选择类型。 您可以使用MainGroup.GroupA.Name等。可能是你发布的代码只是一个例子吗?

以下方法应反映基本结构并适合您的目的。

        static String Reflect(Object data)
        {
            StringBuilder stringBuilder = new StringBuilder();

            foreach (PropertyInfo propertyInfo in data.GetType().GetProperties())
            {
                if (propertyInfo.PropertyType.IsClass && propertyInfo.PropertyType != typeof(String))
                {
                    stringBuilder.AppendFormat("{0} : {1} {2}", propertyInfo.Name, Environment.NewLine 
                        , Reflect(propertyInfo.GetValue(data, null)));
                }
                else
                {
                   stringBuilder.AppendFormat("{0} = {1}, {2}", propertyInfo.Name,  propertyInfo.GetValue(data, null), Environment.NewLine);
                }
            }

            return stringBuilder.ToString();
        }

用法:

            MainGroup main = new MainGroup
            {
                A = new GroupA { Name = "GroupA", ID = 1 },
                B = new GroupB { Date = DateTime.UtcNow },
                C = new GroupC { HasData = false }
            };

            Reflect(main);