【问题标题】:Is there a way to validate values of a dictionary [duplicate]有没有办法验证字典的值[重复]
【发布时间】:2012-09-05 17:52:56
【问题描述】:

可能重复:
C# dictionary type with unique keys and values

我想确保字典具有唯一的键和值。有没有办法在建立我自己的课程之外添加这种验证?这是我能想到的对字典中的值进行验证的唯一方法。但是,也许我可以添加一些我似乎无法通过 google 找到的属性。

如果有帮助,我也希望将此字典与 WPF 绑定一起使用。

【问题讨论】:

  • 不要认为有任何属性会做这样的事情。这取决于字典的实现。最好的办法是用您自己的类包装它(即使您不想这样做),或者编写一个 Linq 查询或实用方法来检查现有字典。
  • 创建两个字典new Dictionary<TKey,TValue>()new Dictionary<TValue,TKey>()
  • 您的意思是唯一键的唯一值。???
  • 数据是否假定为常量,或者如果字典中的值发生变化,那么它就等于另一个值。只需在字典不知道的情况下更改值的实例......(我想知道普通字典如何处理键对象变得相等的类似效果。)
  • @L.B 这对我的目的不起作用(我已更新我将在 WPF 数据绑定中使用它)

标签: c# validation dictionary .net-3.5


【解决方案1】:

根据定义,字典键是唯一的。确保字典值的唯一性与检查每个数组或集合成员的唯一性相同。

.NET 3.5 引入了HashSet<T>,它可以加快速度,假设您的 TValue 类型实现了Equals(TValue)

HashSet<TValue> seenValues = new HashSet<TValue>();
foreach(TKey key in myDictionary) {
    if( seenValues .Contains( myDictionary[key] ) ) throw new Exception("Dictionary contains duplicate item.");
    seenValues .Add( myDictionary[key] );
}

【讨论】:

  • 或者只是foreach(TValue value in myDictionary.Values)
  • 是的,你是对的。最初我认为.Values 属性不能保证以与.Keys 属性相同的顺序返回值(例如自动删除重复值),但 MSDN 文档说它确实如此,太好了。
  • 正如指定的那样,我正在寻找不需要编写自己的课程的东西......开箱即用......猜猜什么都没有
  • 但是你不需要用我给的例子写一个新的类。
【解决方案2】:

您可以尝试使用这个双向字典类:

public class Map<T1, T2>
{
    private Dictionary<T1, T2> _forward = new Dictionary<T1, T2>();
    private Dictionary<T2, T1> _reverse = new Dictionary<T2, T1>();

    public Map()
    {
        this.Forward = new Indexer<T1, T2>(_forward);
        this.Reverse = new Indexer<T2, T1>(_reverse);
    }

    public class Indexer<T3, T4>
    {
        private Dictionary<T3, T4> _dictionary;
        public Indexer(Dictionary<T3, T4> dictionary)
        {
            _dictionary = dictionary;
        }
        public T4 this[T3 index]
        {
            get { return _dictionary[index]; }
            set { _dictionary[index] = value; }
        }
    }

    public void Add(T1 t1, T2 t2)
    {
        _forward.Add(t1, t2);
        _reverse.Add(t2, t1);
    }

    public Indexer<T1, T2> Forward { get; private set; }
    public Indexer<T2, T1> Reverse { get; private set; }
}

你可以这样使用它:

var map = new Map<int, string>();

map.Add(42, "Hello");

Console.WriteLine(map.Forward[42]);
// Outputs "Hello"

Console.WriteLine(map.Reverse["Hello"]);
//Outputs 42

这是一个相当简单的实现。您可能需要公开一些底层字典功能,但至少这是一个开始。

【讨论】:

    最近更新 更多