Есть ли способ добавить синтаксис ключ / значение к объекту в C #? - PullRequest
0 голосов
/ 30 августа 2018

У меня есть объект, который называется CottonCandy. CottonCandy имеет несколько свойств:

  • Масса
  • Объем
  • TotalSugar
  • Цвет

Было бы замечательно, если бы я мог добавить что-то в CottonCandy, чтобы я мог получить такие свойства:

var colors = cottonCandy["Colors"];

Из чтения этого похоже, что вы можете получить значение с помощью:

cottonCandy.GetType().GetProperty("Colors").GetValue(cottonCandy, null);

, и вы можете легко обернуть это в методе:

var colors = cottonCandy.GetPropertyValue("Colors");

но я бы действительно предпочел синтаксис ключ / значение cottonCandy["Colors"]. Есть ли способ сделать это?

Ответы [ 5 ]

0 голосов
/ 30 августа 2018

Вы можете сделать это

public class CottonCandy
    {

        public string Mass { get; set; }
        public string Volume { get; set; }
        public string TotalSugar { get; set; }
        public string Colors { get; set; }
        public string this[string key]
        {
            get
            {
                switch (key)
                {
                    case "Mass":
                        return this.Mass;
                    case "Volume":
                        return this.Volume;
                    case "TotalSugar":
                        return this.TotalSugar;
                    case "Colors":
                        return this.Colors;
                    default:
                        return "";
                }

            }
            set
            {
                switch (key)
                {
                    case "Mass":
                        this.Mass = value; break;
                    case "Volume":
                        this.Volume = value; break;
                    case "TotalSugar":
                        this.TotalSugar = value; break;
                    case "Colors":
                        this.Colors = value; break;
                    default:
                        break;
                }
            }
        }


    }
0 голосов
/ 30 августа 2018

Попробуйте взглянуть на индексаторы объектов: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/indexers/

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

Однако убедитесь, что это действительно то, что вам действительно нужно, потому что вы больше не получаете преимуществ от проверки времени компиляции, если вы обращаетесь к свойствам таким способом.

0 голосов
/ 30 августа 2018

Это не синтаксис ключа / vaue. Однако, если вы решите использовать расширения, вы можете использовать эти методы расширения. В этом Nuget пакете

есть похожие расширения.
public static T GetFieldValue<T>(this object obj, string fieldName)
{
    T result;
    PropertyInfo propertyInfo = obj.GetType().GetProperty(fieldName);
    if (propertyInfo != null)
    {
        result = (T)propertyInfo.GetValue(obj);
    }
    else
    {
        throw new FieldAccessException($"{fieldName} cannot be found");
    }
    return result;
}

Вы можете получить доступ к дополнительным номерам через по этой ссылке . Возможно модульные тесты дают представление об использовании методов и результатах.

UPDATE:

Вы можете комбинировать метод расширения и индексатор следующим образом:

public class TestClass
{
    public string this[string field]
    {
        get => this.GetFieldValue<string>(field);
        set => this.TrySetFieldValue(field, value);
    }
}
0 голосов
/ 30 августа 2018

Существует способ на самом деле. Вы можете использовать indexers . Но вам нужно иметь одинаковые типы полей или поля значений object.

class CottonCandy
{
    private int Mass { get; set; }
    private int Volume { get; set; }
    private int TotalSugar { get; set; }
    private int Colors { get; set; }

    public int this[string field]
    {
        get
        {
            PropertyInfo propertyInfo = typeof(CottonCandy).GetProperty(field);
            if(propertyInfo == null)
                throw new ArgumentException("Invalid field");
            return (int)propertyInfo.GetValue(this);
        }
    }
}
0 голосов
/ 30 августа 2018

Если ваш класс представляет собой простой объект данных без какого-либо поведения и только с такими простыми свойствами, вы можете сделать его Dictionary вместо:

var map = new Dictionary<string, whatever> { { "Colors", ... }, { "Mass", ... } ... };
map["Colors"] = ...;

В противном случае вы должны использовать отражение, как вы уже упоминали.

...