我在这里看过有关如何制作每个键具有多个值的字典的帖子,例如此链接中提供的解决方案之一:
似乎我必须使用List<>作为键的值,以便键可以存储多个值。
如果要添加值,链接中的解决方案就可以了。但我现在的问题是如何从单个键中删除特定值。
我有这个代码用于向字典添加值:
private Dictionary<TKey, List<TValue>> mEventDict;
// this is for initializing the dictionary
public void Subscribe(eVtEvtId inEvent, VtEvtDelegate inCallbackMethod)
{
if (mEventDict.ContainsKey(inEvent))
{
mEventDict[inEvent].Add(inCallbackMethod);
}
else
{
mEventDict.Add(inEvent, new List<TValue>() { v });
}
}
// this is for adding values to the dictionary.
// if the "key" (inEvent) is not yet present in the dictionary,
// the key will be added first before the value
我现在的问题是从密钥中删除特定值。我有这段代码:
public void Unsubscribe(eVtEvtId inEvent, VtEvtDelegate inCallbackMethod)
{
try
{
mEventDict[inEvent].Remove(inCallbackMethod);
}
catch (ArgumentNullException)
{
MessageBox.Show("The event is not yet present in the dictionary");
}
}
基本上,我所做的只是用Add()替换Add()。这有用吗?
此外,如果您对代码有任何问题或疑问(初始化等),请随时询问。
感谢您的建议。
答案 0 :(得分:2)
TylerOhlsen的回答是向正确方向迈出的一步,但它有6个键查找(调用Remove,ContainsKey和索引器)。使用TryGetValue可以将其减少到三个:
private Dictionary<TKey, List<TValue>> mEventDict;
public void Subscribe(TKey inEvent, TValue inCallbackMethod)
{
List<TValue> list;
if (mEventDict.TryGetValue(inEvent, out list))
list.Add(inCallbackMethod);
else
mEventDict.Add(inEvent, new List<TValue> { inCallbackMethod });
}
public bool Unsubscribe(TKey inEvent, TValue inCallbackMethod)
{
List<TValue> list;
if (!mEventDict.TryGetValue(inEvent, out list))
return false;
bool removed = list.Remove(inCallbackMethod);
if (list.Count == 0)
mEventDict.Remove(inEvent);
return removed;
}
如果您不关心删除空列表:
public bool Unsubscribe(TKey inEvent, TValue inCallbackMethod)
{
List<TValue> list;
if (!mEventDict.TryGetValue(inEvent, out list))
return false;
return list.Remove(inCallbackMethod);
}
如果您不需要报告项目是否在列表中(并因此从中删除),请将返回类型更改为void,并(在第一个版本中)删除removed
变量
答案 1 :(得分:1)
会起作用吗?不完全是你想要的......
这是我建议的......
private Dictionary<TKey, List<TValue>> mEventDict;
public void Subscribe(TKey inEvent, TValue inCallbackMethod)
{
if (!mEventDict.ContainsKey(inEvent))
mEventDict.Add(inEvent, new List<TValue>());
mEventDict[inEvent].Add(inCallbackMethod);
}
public bool Unsubscribe(TKey inEvent, TValue inCallbackMethod)
{
if (!mEventDict.ContainsKey(inEvent))
return false;
bool removed = mEventDict[inEvent].Remove(inCallbackMethod);
if (mEventDict[inEvent].Count == 0)
mEventDict.Remove(inEvent);
return removed;
}
注意:我没有测试过这段代码,所以试试吧。此外,此代码不线程安全。
答案 2 :(得分:0)
@phoog - 所以我想将Unsubscribe方法保留为void
。在修改代码之后,这就是我想出来的......
public void Unsubscribe(TKey inEvent, TValue inCallbackMethod)
{
List<TValue> list;
bool mRemoved = false.
if (mEventDict.TryGetValue(inEvent, out list))
{
list.Remove(inCallbackMethod);
mRemoved = true;
}
}
是必需的listRemoved
变量吗?但话说回来,如果在列表中找不到inCallbackMethod
,我认为不会发生任何事情。