代码之家  ›  专栏  ›  技术社区  ›  user875234

有没有一种方法可以将键/值语法添加到C#中的对象?

  •  0
  • user875234  · 技术社区  · 7 年前

    • 体积
    • 颜色

    如果我能在CottonCandy中添加一些东西,这样我就可以检索如下属性:

    var colors = cottonCandy["Colors"];
    

    this 看起来您可以通过以下方式获得值:

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

    你可以很容易地用一种方法:

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

    但我更喜欢键/值语法 cottonCandy["Colors"]

    5 回复  |  直到 7 年前
        1
  •  6
  •   rattrapper    7 年前

    其实有办法。你可以用 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);
            }
        }
    }
    
        2
  •  2
  •   ravichandra vydhya    7 年前

    你能做到的

    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;
                    }
                }
            }
    
    
        }
    
        3
  •  1
  •   Emil Roman    7 年前

    尝试查看对象索引器: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/indexers/

    但是,请确保这确实是您真正想要的,因为如果您以这种方式访问属性,您将不再获得编译时检查的好处。

        4
  •  1
  •   Adem Catamak    7 年前

    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;
    }
    

    this link unit tests 提供有关方法用法和结果的线索。

    更新:

    您可以这样组合扩展方法和索引器:

    public class TestClass
    {
        public string this[string field]
        {
            get => this.GetFieldValue<string>(field);
            set => this.TrySetFieldValue(field, value);
        }
    }
    
        5
  •  0
  •   MakePeaceGreatAgain    7 年前

    如果你的类是一个简单的数据对象,没有任何行为,只有这样简单的属性,那么你可以把它变成一个 Dictionary 取而代之的是:

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