【问题标题】:How to make dynamic value in IDictionary如何在 IDictionary 中制作动态值
【发布时间】:2020-05-25 18:39:01
【问题描述】:

我有一个使用字典的类。它有一个字符串键和对象值:

public class MyClass
{
    public MyClass()
    {
        DynamicProperties.Add("Person", this.Person);
    }

    public IPerson Person { get; set; }
    public IDictionary<string, object> DynamicProperties { get; set; } = new Dictionary<string, object>();
}

如您所见,我在类中有 IPerson 接口属性,我将其添加到字典中。 Student 和 Teacher 类正在实现这个接口:

public interface IPerson
{

}

public class Student : IPerson
{

}

public class Teacher : IPerson
{

}

我想按键获取该字典的当前值。这是我的代码:

    static void Main(string[] args)
    {
        var myclass = new MyClass();
        myclass.Person = new Student();
        var studentFromDictionary = myclass.DynamicProperties["Person"]; // It should be Student
        myclass.Person = new Teacher();
        var teacherFromDictionary = myclass.DynamicProperties["Person"]; // It should be Teacher
    }

我该怎么做? (我可以使用唯一实现 IDictionary 的字典)

【问题讨论】:

  • 字典中的每个键下可能只有一个对象,所以你根本不能在同一个"Person"键下故事StudentTeacher实例
  • 另外,您的构造函数将"Person" 设置为null。此外,更改 myclass.Person 不会影响您的 myclass.DynamicProperties
  • @vasily.sib 是的,这就是我寻找解决方案的原因
  • @vasily.sib 即使“Person”未设置为空也不会影响)

标签: c# dictionary dynamic


【解决方案1】:

您可以在您的 getter 和 setter 中实现自定义逻辑,因此将您的 Person 属性扩展为带有支持字段的显式实现并在那里管理字典:

public class MyClass
    {
        private IPerson _person;

        public MyClass()
        {
            DynamicProperties.Add("Person", this.Person);
        }

        public IPerson Person
        {
            get
            {
                return _person;
            }
            set
            {
                DynamicProperties["Person"] = value;
                _person = value;
            }
        }

        public IDictionary<string, object> DynamicProperties { get; set; } = new Dictionary<string, object>();
    }

UPD

你也可以让你的MyClass 像这样实现IDictionary 这样你就不需要DynamicProperties 属性:

public class MyClass : IReadOnlyDictionary<string, object>
{
    public string Prop { get; set; }

    // can be build via reflection
    private static Dictionary<string, Func<MyClass, object>> _dic = new Dictionary<string, Func<MyClass, object>>
    {
        {nameof(MyClass.Prop), (Func<MyClass, object>)(mc => mc.Prop)}      
    };

    public object this[string key] => _dic[key](this);

    public IEnumerable<string> Keys => _dic.Keys;

    public IEnumerable<object> Values => _dic.Values.Select(func => func(this));

    public int Count => _dic.Count;

    public bool ContainsKey(string key) => _dic.ContainsKey(key);

    public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
    {
        return _dic.Select(kvp => KeyValuePair.Create(kvp.Key, kvp.Value(this))).GetEnumerator();
    }

    public bool TryGetValue(string key, [MaybeNullWhen(false)] out object value)
    {
        value = null;
        if(_dic.ContainsKey(key))
        {
            value = this[key];
            return true;
        }
        return false;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

及用法:

var prop = new MyClass() {Prop = "Test"}["Prop"]; // prop = "Test"

【讨论】:

    猜你喜欢
    • 2021-09-17
    • 2020-10-18
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    相关资源
    最近更新 更多