【问题标题】:Looping through struct in class with reflection使用反射循环遍历类中的结构
【发布时间】:2018-10-19 14:40:22
【问题描述】:
public struct volt_struct
{
    public string volt1;
    public string volt2;
    public string volt2;
    public string volt3;
}
private class Injection_class
{
    public volt_struct stru1;
    public volt_struct stru2;
    public volt_struct stru3;
    public volt_struct stru4;
    public volt_struct stru5;
    public volt_struct stru6;
}

public void main()
{
    Injection_class Time = new Injection_class();

    //Here is code that fills Time with Time values as string type

    string s="";
    FieldInfo[] fi_inner = Time.stru1.GetType().GetFields();
    FieldInfo[] fi_outer = Time.GetType().GetFields();

    // This part is wrong, but shows what I want to achive.
    foreach(FieldInfo field_outer in fi_outer)
    {
        foreach(FieldInfo field_inner in fi_inner)
        {
            s = string.concat(s+field_outer.field_inner.GetValue(Time) + ";");
        }
    }

}

我想使用反射将存储在 Time 中的字符串连接到字符串 s 中。稍后我必须修改类和结构,我不想调整连接代码。

通过对类中的每个结构使用 foreach 循环,我得到了我想要的结果。

 foreach (FieldInfo field in fi_inner)
{
    s = string.Concat(s + field.GetValue(Time.stru1) + ";");
    //field.SetValue(Time, "not measured"); //reset value
}
foreach (FieldInfo field in fi_inner)
{
    s = string.Concat(s + field.GetValue(Time.stru2) + ";");
    //field.SetValue(Time, "not measured"); //reset value
}
//and so one for each other struct

我想像我给出的第一个示例一样实现它。 这可能吗?

【问题讨论】:

    标签: c# class struct reflection nested


    【解决方案1】:

    您可以更轻松地做到这一点而无需反思。像这样更改结构和类:

    public struct volt
    {
        private string[] _volts = new string[4];
        public string[] volts {get {return _volts;} }
    
        public string volt1 {
           get {return _volts[0];}
           set {_volts[0] = value;}
        }
        public string volt2 {
           get {return _volts[1];}
           set {_volts[1] = value;}
        }
        public string volt3 {
           get {return _volts[2];}
           set {_volts[2] = value;}
        }
        public string volt4 {
           get {return _volts[3];}
           set {_volts[3] = value;}
        }
    }
    
    private class Injection
    {
        private _volt[] = new volt[5];
    
        public volt[] {get {return _volt;} }
    
        public volt stru1 {
            get {return _volt[0];}
            set {_volt[0] = value;}
        }
        public volt stru2 {
            get {return _volt[1];}
            set {_volt[1] = value;}
        }
        public volt stru3 {
            get {return _volt[2];}
            set {_volt[2] = value;}
        }
        public volt stru4 {
            get {return _volt[3];}
            set {_volt[3] = value;}
        }
        public volt stru5 {
            get {return _volt[4];}
            set {_volt[4] = value;}
        }
        public volt stru6 {
            get {return _volt[5];}
            set {_volt[5] = value;}
        }
    }
    

    现在您可以使用漂亮、方便的数组了:

    public void main()
    {
        Injection Time = new Injection();
    
        //Here is code that fills Time with Time values as string type
    
        string result = "";
        foreach(volt v in Time.volt)
        {
            foreach(string s in v.volts)
            {
               result += s + ";"
            }
        }
        Console.WriteLine(result);
    }
    

    【讨论】:

    • 感谢您的建议。我将在以后编写的代码中考虑它。但对于这个问题,我认为@MarkRabjohn 给了我更好的答案。
    【解决方案2】:

    在“field_inner”上运行的 FieldInfo 属性需要对“volt_struct”类型对象的引用,因此 Time 在这里不起作用。您需要先在“field_outer”上执行 GetValue,如下所示:

    foreach(FieldInfo field_outer in fi_outer)
    {
        var outer_object = field_outer.GetValue(Time);
        if (outer_object == null) throw someexception;
    
        foreach (FieldInfo field_inner in fi_inner)
        {
            s = string.concat(s+field_inner.GetValue(outer_object) + ";");
        }
    }
    

    如果您想改变父子类型,您可以将它们作为 System.Type 参数传入,或者您可以编写一个具有两个类型参数的通用函数。您也可以将“fi_inner =”移动到外循环并执行 fi_inner = outer_object.GetType().GetFields()。这将连接任何类型的任何子对象上的字符串。

    【讨论】:

    • 这行得通。但是为了 OP 的缘故,我还想建议向 Injection_class 添加一个额外的 volt_struct[] 属性并将该数组用于循环。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    相关资源
    最近更新 更多