用预估的键定义字典

本文关键字:定义 字典 | 更新日期: 2023-09-27 18:13:57

我有一个类Properties,在这个类中我定义了一个像这样的字典:

 public class Properties
    {
        public IDictionary<string, string> ExtendedProperties
        {
            get;
            set;
        }
    }

在字典中,将有3个键始终存在,如Name, NumberAge,并可在运行时添加更多的KeyValuePairs

我想让上面描述的3个键在默认情况下出现在字典中,当我在代码中初始化它时,这样我就可以像这样直接使用它:

Properties objProps = new Properties();
objProps.ExtendedProperties["Name"] = "SomeName";

我知道我可以在我的代码中通过将KeyValuePair添加到字典中来实现这一点,但我希望使用get-set直接在类中设置它以包含3个键。我在课堂上找不到任何解决方案。我研究了这个用预定义的键创建字典,但没有发现它令人满意。

我怎样才能做到这一点?

用预估的键定义字典

从c# 6开始,你可以这样做:

using System;
using System.Collections.Generic;
public class Properties
{
    public IDictionary<string, string> ExtendedProperties { get; set; }
    public Properties(string name, string number, string age) 
    {
        this.ExtendedProperties = new Dictionary<string, string>() 
        { 
            ["Name"] = name,
            ["Number"] = number,
            ["Age"] = age
        };
    }
}

如你所见,你需要在构造函数中定义它。

还有一些很酷的函数你可能想使用:

public int this[int param]
{
    get { return array[param]; }
    set { array[param] = value; }
}

文档

如果你添加这样的内容,你可以输入new Properties()["Name"]

代码示例:

using System;
using System.Collections.Generic;
public class Properties
{
    private IDictionary<string, string> extendedProperties;
    public string this[string key] 
    {
        get { return extendedProperties[key]; }
        set { extendedProperties[key] = value; }        
    }
    public Properties() 
    {
        this.extendedProperties = new Dictionary<string, string>() 
        { 
            ["Name"] = "something",
            ["Number"] = "something",
            ["Age"] = "something"
        };
    }
}

像这样:

public class Properties
    {
        public IDictionary<string, string> ExtendedProperties
        {
            get;
            set;
        }
      public Properties()
      {
         this.ExtendedProperties = new Dictionary<string, string>()
         {
            { "Name", String.Empty },
            { "Number", String.Empty },
            { "Age", String.Empty },
         };
      }
    }

您可能需要查看一些文档:https://msdn.microsoft.com/en-us/library/bb531208.aspx

如何在构造函数中添加3个条目?

using System;
using System.Collections.Generic;
namespace My.Namespace
{
    public class Properties
    {
        public IDictionary<string, string> ExtendedProperties { get; set; }
        public Properties()
        {
            ExtendedProperties = new Dictionary<string, string>
            {
                ["Name"] = String.Empty,
                ["Number"] = String.Empty,
                ["Age"] = String.Empty
            };
        }
    }
}

你可以这样做。

 public class Properties
 {
     public IDictionary<string, string> ExtendedProperties
     {
         get;
         set;
     }
     public Properties(string [] fields)
     {
         ExtendedProperties = new Dictionary<string, string> ();
         foreach(var s in fields)
         {
             ExtendedProperties.Add(s,string.Empty);
         }
     }
 }

用法:

Properties p = new Properties(new [] {"Name","Number", "Age"});

工作提琴代码

我会去实现IDictionary<string, string>,因为它更安全,更容易与其他密钥扩展:(长类后续)

class Properties : IDictionary<string, string>
{
    private Dictionary<string, string> _staticProps;
    private Dictionary<string, string> _otherProps;
    public Properties()
    {
        _staticProps = new Dictionary<string, string>
        {
            {"Name", "" },
            {"Number", "" },
            {"Age", "" }
        };
        _otherProps = new Dictionary<string, string>();
    }
    public ICollection<string> Keys
    {
        get
        {
            return (ICollection<String>)_otherProps.Keys.Concat(_staticProps.Keys);
        }
    }
    public ICollection<string> Values
    {
        get
        {
            return (ICollection<String>)_otherProps.Values.Concat(_staticProps.Values);
        }
    }
    public int Count
    {
        get
        {
            return _otherProps.Count + _staticProps.Count;
        }
    }
    public bool IsReadOnly
    {
        get
        {
            throw new NotImplementedException();
        }
    }
    public string this[string key]
    {
        get
        {
            if (_otherProps.ContainsKey(key))
            {
                return _otherProps[key];
            }
            if(_staticProps.ContainsKey(key))
            {
                return _staticProps[key];
            }
            throw new KeyNotFoundException(key);
        }
        set
        {
            if (_otherProps.ContainsKey(key) || _staticProps.ContainsKey(key))
            {
                throw new ArgumentException("key exists: " + key);
            }
            _otherProps[key] = value;
        }
    }
    public bool ContainsKey(string key)
    {
        return _otherProps.ContainsKey(key) || _staticProps.ContainsKey(key);
    }
    public void Add(string key, string value)
    {
        _otherProps.Add(key, value);
    }
    public bool Remove(string key)
    {
        if (_staticProps.ContainsKey(key))
        {
            throw new ArgumentException("key is static, cannot be removed: " + key);
        }
        return _otherProps.Remove(key);
    }
    public bool TryGetValue(string key, out string value)
    {
        return _otherProps.TryGetValue(key, out value) || _staticProps.TryGetValue(key, out value);
    }
    public void Add(KeyValuePair<string, string> item)
    {
        if (_staticProps.ContainsKey(item.Key))
        {
            throw new ArgumentException("key exist an is static: " + item.Key);
        }
        _otherProps.Add(item.Key, item.Value);
    }
    public void Clear()
    {
        _otherProps.Clear();
        foreach (var key in _staticProps.Keys)
        {
            _staticProps[key] = string.Empty;
        }
    }
    public bool Contains(KeyValuePair<string, string> item)
    {
        return _otherProps.Contains(item) || _staticProps.Contains(item);
    }
    public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
    {           
        // define yourself how you want to handle arrayIndex between the two dictionaries
    }
    public bool Remove(KeyValuePair<string, string> item)
    {
        if (_staticProps.ContainsKey(item.Key))
        {
            throw new ArgumentException("key is static, cannot be removed: " + item.Key);
        }
        return _otherProps.Remove(item.Key);
    }
    public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
    {
        return _otherProps.Concat(_staticProps).GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return _otherProps.Concat(_staticProps).GetEnumerator();
    }
}

我将把这个逻辑封装在属性本身中:

public class Properties
{
    private IDictionary<string, string> _extendedProperties;
    public IDictionary<string, string> ExtendedProperties
    {
        get
        {
            return
                _extendedProperties == null ?
                    new Dictionary<string, string>() { { "Name", "" }, { "Number", "" }, { "Age", "" } } :
                    _extendedProperties;
        }
        set 
        { 
            _extendedProperties = value; 
            //here you can also check if value misses those key to add them to _extendedProperties
        }
    }
}