Заполнение переменных класса массивом с идентификатором

Есть класс только со свойствами

class SomeStruct{
   public string Paper_1 { get; set; }
   public string Paper_2 { get; set; }
   public string Paper_3 { get; set; }
   ...
}

Каким образом можно заполнить переменные этого класса с помощью цикла, по типу:

SomeStruct someSt = new SomeStruct();
for (int i = 0; i < 5; i++)
{
    someSt[i] = someData[i]
}

или

foreach (var item in someSt) 
{
    item = someData
}

Или как можно обратиться к переменной класса не по имени а по идентификатору?


Ответы (2 шт):

Автор решения: Cost

Если типы всех свойств совпадают, то можно реализовать индексатор:

class SomeStruct
{
    public string Paper_1 { get; set; }
    public string Paper_2 { get; set; }
    public string Paper_3 { get; set; }

    public string this[int i]
    {
        get
        {
            return i switch
            {
                0 => Paper_1,
                1 => Paper_2,
                2 => Paper_3,
            };
        }
        set
        {
            switch (i)
            {
                case 0: Paper_1 = value; break;
                case 1: Paper_2 = value; break;
                case 2: Paper_3 = value; break;
            };
        }
    }
}

И добавить свойство Count, которое будет возвращать количество свойств Paper_X в данном классе

Если свойств очень много, но их имена соответствуют паттерну Paper_X, то можно использовать рефлексию совместно с индексатором:

public string this[int i]
{
    get => PapersProperties[i].GetValue(this).ToString();
    set => PapersProperties[i].SetValue(this, value);
}

Dictionary<int, PropertyInfo> papersProperties;
Dictionary<int, PropertyInfo> PapersProperties => papersProperties ??= GetPapersInfo();

public Dictionary<int, PropertyInfo> GetPapersInfo()
{
    var papersProperties = new Dictionary<int, PropertyInfo>();
    var papers = typeof(SomeStruct).GetProperties().Where(x => x.Name.StartsWith("Paper_"));
    foreach (var paper in papers)
    {
        int key = Convert.ToInt32(paper.Name.Substring(6,1)) - 1;
        papersProperties.Add(key, paper);
    }
    return papersProperties;
}
→ Ссылка
Автор решения: rotabor

"как можно обратиться к переменной класса не по имени а по идентификатору?"

someSt.GetType().GetProperty($"Paper_{i}").SetValue(someSt, newvalue);
var result = someSt.GetType().GetProperty($"Paper_{i}").GetValue(someSt);
→ Ссылка