PowerCollections - 多词典“删除”未找到值时删除所有值

发布于 2024-11-06 21:59:07 字数 786 浏览 0 评论 0原文

我正在使用 http://powercollections.codeplex.com/ 中的 powercollections 库

第一个测试通过了,但是第二次测试失败。如果找不到值,我不希望 Remove 从字典中删除所有项目。

这是一个问题还是我误解了 Remove 的功能?

[Test]
public void passing_test()
{
    var classes = new MultiDictionary<string, object>(false);
    classes.Add("class", "class_name1");
    classes.Add("class", "class_name2");
    classes.Remove("class", "class_name2");

    Assert.AreEqual(1, classes.Count);
}

[Test]
public void failing_test()
{
    var classes = new MultiDictionary<string, object>(false);
    classes.Add("class", "class_name1");
    classes.Remove("class", "class_name2");

    Assert.AreEqual(1, classes.Count);
}

I am using the powercollections library from http://powercollections.codeplex.com/

The first test passes, however the second test fails. I wouldn't expect Remove to remove all items from the dictionary if a value was not found.

Is this an issue or am I misunderstanding how Remove functions ?

[Test]
public void passing_test()
{
    var classes = new MultiDictionary<string, object>(false);
    classes.Add("class", "class_name1");
    classes.Add("class", "class_name2");
    classes.Remove("class", "class_name2");

    Assert.AreEqual(1, classes.Count);
}

[Test]
public void failing_test()
{
    var classes = new MultiDictionary<string, object>(false);
    classes.Add("class", "class_name1");
    classes.Remove("class", "class_name2");

    Assert.AreEqual(1, classes.Count);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对岸观火 2024-11-13 21:59:07

它实际上看起来像代码中的一个错误:

        /// <summary>
        /// Removes a given value from the values associated with a key. If the
        /// last value is removed from a key, the key is removed also.
        /// </summary>
        /// <param name="key">A key to remove a value from.</param>
        /// <param name="value">The value to remove.</param>
        /// <returns>True if <paramref name="value"/> was associated with <paramref name="key"/> (and was
        /// therefore removed). False if <paramref name="value"/> was not associated with <paramref name="key"/>.</returns>
        public sealed override bool Remove(TKey key, TValue value)
        {
            KeyAndValues keyValues = new KeyAndValues(key);
            KeyAndValues existing;

            if (hash.Find(keyValues, false, out existing)) {
                // There is an item in the hash table equal to this key. Find the value.
                int existingCount = existing.Count;
                int valueHash = Util.GetHashCode(value, valueEqualityComparer);
                int indexFound = -1;
                for (int i = 0; i < existingCount; ++i) {
                    if (Util.GetHashCode(existing.Values[i], valueEqualityComparer) == valueHash &&
                        valueEqualityComparer.Equals(existing.Values[i], value)) 
                    {
                        // Found an equal existing value
                        indexFound = i;
                    }
                }

                if (existingCount == 1) {
                    // Removing the last value. Remove the key.
                    hash.Delete(existing, out keyValues);
                    return true;
                }

注意到他们如何检查 existingCount == 1 吗?尽管您输入的值不同,但没有代码可以检查在 hash.Delete 调用之前是否在搜索中找到了索引。解决此问题的正确方法是执行以下操作:

            if (existingCount == 1 && indexFound != -1) {
                // Removing the last value. Remove the key.
                hash.Delete(existing, out keyValues);
                return true;
            }

这是完整的源代码: http ://powercollections.codeplex.com/SourceControl/changeset/view/6259#71508

It actually looks like a bug in the code:

        /// <summary>
        /// Removes a given value from the values associated with a key. If the
        /// last value is removed from a key, the key is removed also.
        /// </summary>
        /// <param name="key">A key to remove a value from.</param>
        /// <param name="value">The value to remove.</param>
        /// <returns>True if <paramref name="value"/> was associated with <paramref name="key"/> (and was
        /// therefore removed). False if <paramref name="value"/> was not associated with <paramref name="key"/>.</returns>
        public sealed override bool Remove(TKey key, TValue value)
        {
            KeyAndValues keyValues = new KeyAndValues(key);
            KeyAndValues existing;

            if (hash.Find(keyValues, false, out existing)) {
                // There is an item in the hash table equal to this key. Find the value.
                int existingCount = existing.Count;
                int valueHash = Util.GetHashCode(value, valueEqualityComparer);
                int indexFound = -1;
                for (int i = 0; i < existingCount; ++i) {
                    if (Util.GetHashCode(existing.Values[i], valueEqualityComparer) == valueHash &&
                        valueEqualityComparer.Equals(existing.Values[i], value)) 
                    {
                        // Found an equal existing value
                        indexFound = i;
                    }
                }

                if (existingCount == 1) {
                    // Removing the last value. Remove the key.
                    hash.Delete(existing, out keyValues);
                    return true;
                }

Notice how they are checking for existingCount == 1? Although the values you entered differ, there is no code to check whether the index was found in the search prior to the hash.Delete call. The correct way to fix this would be to do something like:

            if (existingCount == 1 && indexFound != -1) {
                // Removing the last value. Remove the key.
                hash.Delete(existing, out keyValues);
                return true;
            }

Here's the full source: http://powercollections.codeplex.com/SourceControl/changeset/view/6259#71508

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文