是否可以强制词典具有唯一值?请参阅以下示例。
Dictionary<string, string> types = new Dictionary<string, string>()
{
{"1", "one"},
{"2", "two"},
{"3", "three"}
};
如果有人试图执行以下行,则会收到错误。
types.Add("4","one");
我知道这不是字典的构建方式,而正确的答案可能是使用不同的/自定义数据结构。
答案 0 :(得分:10)
保留两个数据结构;您的常规字典和值HashSet<string>
。如果要添加项目,请先检查该值是否在哈希集中。如果不是,那么你知道添加到字典和集合是安全的。 (还要确保在删除时从两个集合中删除项目。)
如果在足够的地方完成此操作,则可能值得创建自己的IDictionary<K,V>
实施,该实施内部使用常规Dictionary
和HashSet
,因此您不需要在使用它时做了这么多工作。如果这个特定的结构仅在少数地方使用,那么创建这样一个类可能不值得投资。
答案 1 :(得分:6)
您可能希望实现IDictionary
并在内部调用相应的Dictionary<TKey,TValue>
方法。此外,您需要HashSet<TValue>
。然后,在您的添加方法上,您首先要检查是否hashset.Contains(value)
。如果是,则抛出异常。
另一方面,你真的需要这种行为吗?如果你只使用HashSet<Tuple<string,string>>
怎么办?然后,任何重复项都会被忽略。或者你真的需要数据结构来抛出异常吗?如果你不这样做,那就是我要去的地方。
编辑:好点@Alexei Levenkov。如果您使用不同的键具有相同的值,则HashSet方法不会提供您最初请求的内容。这只适用于您期望SAME键/值对的情况。
答案 2 :(得分:4)
在添加
之前检查types.ContainsValue
string str = "one";
if (!types.ContainsValue(str)) //doesn't add if its already there
{
types.Add("4", str);
}
答案 3 :(得分:3)
框架提供的Dictionary
不提供此功能。
最快的解决方法是建立这样的东西
public class UniqueValueDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public new void Add(TKey key, TValue value)
{
if (this.ContainsValue(value))
{
throw new ArgumentException("value already exist");
}
base.Add(key, value);
}
public new TValue this[TKey key]
{
get
{
return base[key];
}
set
{
if (this.ContainsValue(value))
{
throw new ArgumentException("value already exist");
}
base[key] = value;
}
}
}
或类似以下内容(性能更好但内存更好)
public class UniqueValueDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
Dictionary<TValue, TKey> valueAsKey = new Dictionary<TValue, TKey>();
public new void Add(TKey key, TValue value)
{
if (valueAsKey.ContainsKey(value))
{
throw new ArgumentException("value already exist");
}
base.Add(key, value);
valueAsKey.Add(value, key);
}
public new TValue this[TKey key]
{
get
{
return base[key];
}
set
{
if (valueAsKey.ContainsKey(value))
{
throw new ArgumentException("value already exist");
}
if (!this.ContainsKey(key))
{
this.Add(key, value);
}
else
{
base[key] = value;
valueAsKey[value] = key;
}
}
}
//You may need to handle remove as well
}
注意:这仅在您使用UniqueValueDictionary<TKey, TValue>
类型时才有效。如果您转换为Dictionary<TKey, TValue>
,则可以添加重复值。
正如评论中所指出的那样,您可以构建类似这样的内容,继承自IDictionary<TKey, TValue>
而不是Dictionary<TKey, TValue>
。