是否有Dictionary <string,object>集合允许多个键?

Edw*_*uay 5 c# collections

我目前有一个子项目的菜单存储在这个字典变量中:

private Dictionary<string, UserControl> _leftSubMenuItems 
    = new Dictionary<string, UserControl>();
Run Code Online (Sandbox Code Playgroud)

所以我将视图添加到例如"Customer"部分,如下所示:

_leftSubMenuItems.Add("customers", container.Resolve<EditCustomer>());
_leftSubMenuItems.Add("customers", container.Resolve<CustomerReports>());
Run Code Online (Sandbox Code Playgroud)

但由于我使用的是词典,我只能有一个名为"customers"的键.

我的自然倾向是现在创建一个带有"Section"和"View"属性的自定义结构,但是.NET集合是否更适合这个任务,比如"MultiKeyDictionary"?

回答:

感谢maciejkow,我扩展了你的建议,以获得我所需要的:

using System;
using System.Collections.Generic;

namespace TestMultiValueDictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            MultiValueDictionary<string, object> leftSubMenuItems = new MultiValueDictionary<string, object>();

            leftSubMenuItems.Add("customers", "customers-view1");
            leftSubMenuItems.Add("customers", "customers-view2");
            leftSubMenuItems.Add("customers", "customers-view3");
            leftSubMenuItems.Add("employees", "employees-view1");
            leftSubMenuItems.Add("employees", "employees-view2");

            foreach (var leftSubMenuItem in leftSubMenuItems.GetValues("customers"))
            {
                Console.WriteLine(leftSubMenuItem);
            }

            Console.WriteLine("---");

            foreach (var leftSubMenuItem in leftSubMenuItems.GetAllValues())
            {
                Console.WriteLine(leftSubMenuItem);
            }

            Console.ReadLine();
        }
    }

    public class MultiValueDictionary<TKey, TValue> : Dictionary<TKey, List<TValue>>
    {

        public void Add(TKey key, TValue value)
        {
            if (!ContainsKey(key))
                Add(key, new List<TValue>());
            this[key].Add(value);
        }

        public List<TValue> GetValues(TKey key)
        {
            return this[key];
        }

        public List<TValue> GetAllValues()
        {
            List<TValue> list = new List<TValue>();

            foreach (TKey key in this.Keys)
            {
                List<TValue> values = this.GetValues(key);
                list.AddRange(values);
            }

            return list;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

答案2:

感谢Blixt关于yield的提示,这里是GetAllValues的变化:

public IEnumerable<TValue> GetAllValues()
{
    foreach (TKey key in this.Keys)
    {
        List<TValue> values = this.GetValuesForKey(key);
        foreach (var value in values)
        {
            yield return value;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

答案2进一步重构:

感谢Keith,这是一个更简洁的方法来做同样的事情:

public IEnumerable<TValue> GetAllValues()
{
    foreach (var keyValPair in this)
        foreach (var val in keyValPair.Value)
            yield return val;
}
Run Code Online (Sandbox Code Playgroud)

mac*_*kow 10

如果一个键需要可变数量的值,为什么不创建Dictionary<string, List<UserControl>>?此外,您可以继承此类并创建自己的Add,获得您现在使用的相同语法.这样,您可以在添加新控件之前避免手动添加空列表.

......这样:

class MultiValueDictionary<TKey, TValue> : Dictionary<TKey, List<TValue>>
{

   public void Add(TKey key, TValue value)
   {
      if(!ContainsKey(key))
         Add(key, new List<TValue>());
      this[key].Add(value);
   }
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*lls 5

查看NGenericsHashList.它是一个字典,它维护每个键的值列表.Wintellect的PowerCollections库还有一个方便的MultiDictionary类,可以在删除与给定键关联的最后一个值时自动清理.