Динамическая ссылка на объект C # - PullRequest
0 голосов
/ 01 мая 2018

Я создал метод Mydata для назначения новых данных из списка (listData). Но то, как я это делаю, происходит не динамически, и я использую оператор if else, чтобы определить, сколько данных добавить и какому свойству они принадлежат. Есть ли способ упростить это или сделать это динамически, без использования оператора if else.

public List<Data> _newData = new List<Data>();

public void Mydata(int number, List<string> listData) {
             if (number == 1) {
              _newData.Add(new Data() {
                       variable0 = listData[0].ToString(),
                 });
             } 
             else if (number == 2) {
             _newData.Add(new Data() {
                       variable0 = listData[0].ToString(),
                       variable1 = listData[1].ToString(),
                 });    
               }
             else if (number == 3) {
             _newData.Add(new Data() {
                       variable0 = listData[0].ToString(),
                       variable1 = listData[1].ToString(),
                       variable2 = listData[2].ToString(),
                 });    
               } 


class Data
{
  public string variable1 { get; set; }
  public string variable2 { get; set; }
  public string variable3 { get; set; }
  public string variable4 { get; set; }
  ..
  public string variable10 { get; set; }
}

Ответы [ 2 ]

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

Правильное решение: Data следует использовать string[] или List<string> вместо отдельных свойств. Однако его можно эмулировать несколькими способами.

Поскольку C # не имеет ссылок на члены, вы можете использовать делегаты для установки свойств:

public void Mydata(int number, List<string> listData) {
    var nd = new Data();
    var setters = new Action<Data,string>[] {
        (d,s) => d.variable0 = s,
        (d,s) => d.variable1 = s,
        (d,s) => d.variable2 = s,
        (d,s) => d.variable3 = s,
        (d,s) => d.variable4 = s,
        (d,s) => d.variable5 = s,
        (d,s) => d.variable6 = s,
        (d,s) => d.variable7 = s,
        (d,s) => d.variable8 = s,
        (d,s) => d.variable9 = s,
        (d,s) => d.variable10 = s,
    };

    while (number-- > 0)
        setters[number](nd, listData[number]);

    _newData.Add(nd);
}

В качестве альтернативы, вы можете изменить Data для поддержки индексированного свойства, которое возвращает ссылку на поле, хотя это добавляет много накладных расходов к каждому Data1 объекту:

public class Data1 {
    public string variable0;
    public string variable1;
    public string variable2;
    public string variable3;
    public string variable4;
    public string variable5;
    public string variable6;
    public string variable7;
    public string variable8;
    public string variable9;
    public string variable10;

    public delegate ref string RefStringFunc();

    private List<RefStringFunc> refvar;

    public Data1() {
        refvar = new List<RefStringFunc>() {
            () => ref variable0,
            () => ref variable1,
            () => ref variable2,
            () => ref variable3,
            () => ref variable4,
            () => ref variable5,
            () => ref variable6,
            () => ref variable7,
            () => ref variable8,
            () => ref variable9,
            () => ref variable10,
        };
    }

    public ref string this[int index]
    {
        get
        {
            return ref refvar[index]();
        }
    }
}

Затем вы можете использовать индексированное свойство для присвоения значений:

public void Mydata1(int number, List<string> listData) {
    var nd = new Data1();

    while (number-- > 0)
        nd[number] = listData[number];

    _newData.Add(nd);
}

Наконец, вы можете использовать Reflection, но это действительно не лучший способ выразить свое намерение, и это не рекомендуется (хотя он предлагает другой способ эмулировать ссылки на элементы).

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

Если вы хотите сохранить структуру данных такой, какой она есть (не рекомендуется - см. Комментарии), очевидным упрощением кода будет:

var d = new Data
{
    variable0 = listData[0];
};
if (number >= 1) d.variable1 = listData[1];
if (number >= 2) d.variable2 = listData[2];
if (number >= 3) d.variable3 = listData[3];
_newData.Add(d);
...