У меня следующий класс.

public class Unit
{
  public string Name { get; set; }
  public double cConvertFromSI { get; set; }
}

public class UnitList
{
  public Unit m  = new Unit() { Name = "meter", cConvertFromSI = 1 };
  public Unit mm = new Unit() { Name = "millimeter", cConvertFromSI = 1000 };
  public Unit in = new Unit() { Name = "inch", cConvertFromSI = 39.3701 };
}

И я хочу получить все «Unit» из «UnitList».

// I want to do something like

UnitList MyUnitList = new UnitList();

foreach (Unit Unit in MyUnitList)
{
  // do something with each 'Unit'
}

Как я могу это сделать?

c#
0
kk1988 8 Июн 2021 в 22:27

2 ответа

Лучший ответ

Вы можете реализовать интерфейс IEnumerable<Unit>.

    public class UnitList : IEnumerable<Unit>
    {
        public Unit m = new Unit() { Name = "meter", cConvertFromSI = 1 };
        public Unit mm = new Unit() { Name = "millimeter", cConvertFromSI = 1000 };
        public Unit in_ = new Unit() { Name = "inch", cConvertFromSI = 39.3701 };

        public IEnumerator<Unit> GetEnumerator()
        {
            yield return m;
            yield return mm;
            yield return in_;
            //...
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
          => GetEnumerator();
    }

Таким образом, вы можете перебирать экземпляр UnitList с помощью foreach.

foreach ( Unit u in new UnitList() )
{
}

Однако, вероятно, было бы разумнее просто использовать вместо этого свойство List или Array.

3
Olivier Rogier 8 Июн 2021 в 19:48

Я надеюсь, что у вас есть веская причина не просто использовать List<Unit>, но это решит проблему динамического получения свойств.

public class Unit
{
    public string Name { get; set; }
    public double cConvertFromSI { get; set; }

    public override string ToString()
    {
        return $"{Name} {cConvertFromSI}";
    }
}

public class UnitList
{
    public Unit m { get; set; } = new Unit() {Name = "meter", cConvertFromSI = 1};
    public Unit mm { get; set; } = new Unit() {Name = "millimeter", cConvertFromSI = 1000};
    public Unit iN { get; set; } = new Unit() {Name = "inch", cConvertFromSI = 39.3701}; // in is a reserved keyword btw
}

class Program
{
    static void Main(string[] args)
    {
        var unitList = new UnitList();

        var propertyInfos = typeof(UnitList).GetProperties().Where(p => p.PropertyType == typeof(Unit));
        var units = propertyInfos.Select(propertyInfo => (Unit) propertyInfo.GetValue(unitList)).ToList();

        units.ForEach(u => { Console.WriteLine(u.ToString()); });
    }
}

Обратите внимание, что я добавил {get; set;} в конце полей UnitList, чтобы сделать их свойствами.

Если вы хотите сохранить их как поля, вам нужно будет получить такие единицы

   var fields = typeof(UnitList).GetFields().Where(p => p.FieldType == typeof(Unit));
   var units = fields.Select(propertyInfo => (Unit) propertyInfo.GetValue(unitList)).ToList();
2
LLL 8 Июн 2021 в 19:42