Цикл по структуре в классе с отражением - PullRequest
0 голосов
/ 09 мая 2018
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

Я хочу добиться этого, как в первом примере, который я привел. Это возможно?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Вы можете сделать это намного проще, не задумываясь. Измените структуру и класс следующим образом:

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);
}
0 голосов
/ 09 мая 2018

Свойства FieldInfo, которые работают с 'field_inner', нуждаются в ссылке на объект типа 'volt_struct', поэтому Time здесь не будет работать. Сначала вы должны выполнить GetValue для field_outer, примерно так:

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 (). Это объединит строки в любом дочернем объекте любого типа.

...