C#中的双向1对1字典

C#中的双向1对1字典

我正在寻找C#(2)中的通用双向1到1字典类,即。a BiDictionaryOneToOne<T, S>保证只包含每个值和键中的一个(无论如何最多为RefEquals),并且可以使用键或值进行搜索。有人知道,或者我应该自己实施吗?我不敢相信我是第一个需要这个的人......

这个问题的答案中有一个BiDictionary ,但它不适用于唯一元素(并且也不实现RemoveByFirst(T t)或RemoveBySecond(S s))。


一只斗牛犬
浏览 1185回答 3
3回答

慕标琳琳

好的,这是我的尝试(建立在Jon的 - 谢谢),存档在这里并开放改进:///&nbsp;<summary>///&nbsp;This&nbsp;is&nbsp;a&nbsp;dictionary&nbsp;guaranteed&nbsp;to&nbsp;have&nbsp;only&nbsp;one&nbsp;of&nbsp;each&nbsp;value&nbsp;and&nbsp;key.&nbsp;///&nbsp;It&nbsp;may&nbsp;be&nbsp;searched&nbsp;either&nbsp;by&nbsp;TFirst&nbsp;or&nbsp;by&nbsp;TSecond,&nbsp;giving&nbsp;a&nbsp;unique&nbsp;answer&nbsp;because&nbsp;it&nbsp;is&nbsp;1&nbsp;to&nbsp;1.///&nbsp;</summary>///&nbsp;<typeparam&nbsp;name="TFirst">The&nbsp;type&nbsp;of&nbsp;the&nbsp;"key"</typeparam>///&nbsp;<typeparam&nbsp;name="TSecond">The&nbsp;type&nbsp;of&nbsp;the&nbsp;"value"</typeparam>public&nbsp;class&nbsp;BiDictionaryOneToOne<TFirst,&nbsp;TSecond>{ &nbsp;&nbsp;&nbsp;&nbsp;IDictionary<TFirst,&nbsp;TSecond>&nbsp;firstToSecond&nbsp;=&nbsp;new&nbsp;Dictionary<TFirst,&nbsp;TSecond>(); &nbsp;&nbsp;&nbsp;&nbsp;IDictionary<TSecond,&nbsp;TFirst>&nbsp;secondToFirst&nbsp;=&nbsp;new&nbsp;Dictionary<TSecond,&nbsp;TFirst>(); &nbsp;&nbsp;&nbsp;&nbsp;#region&nbsp;Exception&nbsp;throwing&nbsp;methods &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Tries&nbsp;to&nbsp;add&nbsp;the&nbsp;pair&nbsp;to&nbsp;the&nbsp;dictionary. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Throws&nbsp;an&nbsp;exception&nbsp;if&nbsp;either&nbsp;element&nbsp;is&nbsp;already&nbsp;in&nbsp;the&nbsp;dictionary &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="first"></param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="second"></param> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Add(TFirst&nbsp;first,&nbsp;TSecond&nbsp;second) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(firstToSecond.ContainsKey(first)&nbsp;||&nbsp;secondToFirst.ContainsKey(second)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ArgumentException("Duplicate&nbsp;first&nbsp;or&nbsp;second"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstToSecond.Add(first,&nbsp;second); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;secondToFirst.Add(second,&nbsp;first); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Find&nbsp;the&nbsp;TSecond&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;TFirst&nbsp;first &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Throws&nbsp;an&nbsp;exception&nbsp;if&nbsp;first&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;dictionary. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="first">the&nbsp;key&nbsp;to&nbsp;search&nbsp;for</param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<returns>the&nbsp;value&nbsp;corresponding&nbsp;to&nbsp;first</returns> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;TSecond&nbsp;GetByFirst(TFirst&nbsp;first) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TSecond&nbsp;second; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!firstToSecond.TryGetValue(first,&nbsp;out&nbsp;second)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ArgumentException("first"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;second;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Find&nbsp;the&nbsp;TFirst&nbsp;corresponing&nbsp;to&nbsp;the&nbsp;Second&nbsp;second. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Throws&nbsp;an&nbsp;exception&nbsp;if&nbsp;second&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;dictionary. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="second">the&nbsp;key&nbsp;to&nbsp;search&nbsp;for</param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<returns>the&nbsp;value&nbsp;corresponding&nbsp;to&nbsp;second</returns> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;TFirst&nbsp;GetBySecond(TSecond&nbsp;second) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TFirst&nbsp;first; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!secondToFirst.TryGetValue(second,&nbsp;out&nbsp;first)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ArgumentException("second"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;first;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Remove&nbsp;the&nbsp;record&nbsp;containing&nbsp;first. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;If&nbsp;first&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;dictionary,&nbsp;throws&nbsp;an&nbsp;Exception. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="first">the&nbsp;key&nbsp;of&nbsp;the&nbsp;record&nbsp;to&nbsp;delete</param> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;RemoveByFirst(TFirst&nbsp;first) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TSecond&nbsp;second; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!firstToSecond.TryGetValue(first,&nbsp;out&nbsp;second)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ArgumentException("first"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstToSecond.Remove(first); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;secondToFirst.Remove(second); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Remove&nbsp;the&nbsp;record&nbsp;containing&nbsp;second. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;If&nbsp;second&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;dictionary,&nbsp;throws&nbsp;an&nbsp;Exception. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="second">the&nbsp;key&nbsp;of&nbsp;the&nbsp;record&nbsp;to&nbsp;delete</param> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;RemoveBySecond(TSecond&nbsp;second) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TFirst&nbsp;first; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!secondToFirst.TryGetValue(second,&nbsp;out&nbsp;first)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ArgumentException("second"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;secondToFirst.Remove(second); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstToSecond.Remove(first); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;#endregion &nbsp;&nbsp;&nbsp;&nbsp;#region&nbsp;Try&nbsp;methods &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Tries&nbsp;to&nbsp;add&nbsp;the&nbsp;pair&nbsp;to&nbsp;the&nbsp;dictionary. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Returns&nbsp;false&nbsp;if&nbsp;either&nbsp;element&nbsp;is&nbsp;already&nbsp;in&nbsp;the&nbsp;dictionary&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="first"></param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="second"></param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<returns>true&nbsp;if&nbsp;successfully&nbsp;added,&nbsp;false&nbsp;if&nbsp;either&nbsp;element&nbsp;are&nbsp;already&nbsp;in&nbsp;the&nbsp;dictionary</returns> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Boolean&nbsp;TryAdd(TFirst&nbsp;first,&nbsp;TSecond&nbsp;second) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(firstToSecond.ContainsKey(first)&nbsp;||&nbsp;secondToFirst.ContainsKey(second)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstToSecond.Add(first,&nbsp;second); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;secondToFirst.Add(second,&nbsp;first); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Find&nbsp;the&nbsp;TSecond&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;TFirst&nbsp;first. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Returns&nbsp;false&nbsp;if&nbsp;first&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;dictionary. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="first">the&nbsp;key&nbsp;to&nbsp;search&nbsp;for</param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="second">the&nbsp;corresponding&nbsp;value</param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<returns>true&nbsp;if&nbsp;first&nbsp;is&nbsp;in&nbsp;the&nbsp;dictionary,&nbsp;false&nbsp;otherwise</returns> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Boolean&nbsp;TryGetByFirst(TFirst&nbsp;first,&nbsp;out&nbsp;TSecond&nbsp;second) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;firstToSecond.TryGetValue(first,&nbsp;out&nbsp;second); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Find&nbsp;the&nbsp;TFirst&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;TSecond&nbsp;second. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Returns&nbsp;false&nbsp;if&nbsp;second&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;dictionary. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="second">the&nbsp;key&nbsp;to&nbsp;search&nbsp;for</param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="first">the&nbsp;corresponding&nbsp;value</param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<returns>true&nbsp;if&nbsp;second&nbsp;is&nbsp;in&nbsp;the&nbsp;dictionary,&nbsp;false&nbsp;otherwise</returns> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Boolean&nbsp;TryGetBySecond(TSecond&nbsp;second,&nbsp;out&nbsp;TFirst&nbsp;first) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;secondToFirst.TryGetValue(second,&nbsp;out&nbsp;first); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Remove&nbsp;the&nbsp;record&nbsp;containing&nbsp;first,&nbsp;if&nbsp;there&nbsp;is&nbsp;one. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="first"></param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<returns>&nbsp;If&nbsp;first&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;dictionary,&nbsp;returns&nbsp;false,&nbsp;otherwise&nbsp;true</returns> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Boolean&nbsp;TryRemoveByFirst(TFirst&nbsp;first) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TSecond&nbsp;second; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!firstToSecond.TryGetValue(first,&nbsp;out&nbsp;second)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstToSecond.Remove(first); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;secondToFirst.Remove(second); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Remove&nbsp;the&nbsp;record&nbsp;containing&nbsp;second,&nbsp;if&nbsp;there&nbsp;is&nbsp;one. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<param&nbsp;name="second"></param> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<returns>&nbsp;If&nbsp;second&nbsp;is&nbsp;not&nbsp;in&nbsp;the&nbsp;dictionary,&nbsp;returns&nbsp;false,&nbsp;otherwise&nbsp;true</returns> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Boolean&nbsp;TryRemoveBySecond(TSecond&nbsp;second) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TFirst&nbsp;first; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!secondToFirst.TryGetValue(second,&nbsp;out&nbsp;first)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;secondToFirst.Remove(second); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstToSecond.Remove(first); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;#endregion&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;The&nbsp;number&nbsp;of&nbsp;pairs&nbsp;stored&nbsp;in&nbsp;the&nbsp;dictionary &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Int32&nbsp;Count &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get&nbsp;{&nbsp;return&nbsp;firstToSecond.Count;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;<summary> &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Removes&nbsp;all&nbsp;items&nbsp;from&nbsp;the&nbsp;dictionary. &nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;</summary> &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Clear() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstToSecond.Clear(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;secondToFirst.Clear(); &nbsp;&nbsp;&nbsp;&nbsp;}}
打开App,查看更多内容
随时随地看视频慕课网APP