【问题标题】:Microsoft.Maintainability Error with List Extension Methods列表扩展方法的 Microsoft.Maintainability 错误
【发布时间】:2011-09-29 23:22:51
【问题描述】:

所以我尝试为List 创建一些基本的扩展方法。基本上我有一个 UniqueAdd 和 UniqueAddRange。它将在添加之前检查值是否存在,如果它已经在列表中,则不会添加它。代码如下:

public static class ListExtensions
{
    /// <summary>
    /// Adds only the values in the 'values' collection that do not already exist in the list. Uses list.Contains() to determine existence of
    /// previous values.
    /// </summary>
    /// <param name="list"></param>
    /// <param name="values"></param>
    public static void UniqueAddRange<T>(this List<T> list, IEnumerable<T> values)
    {
        foreach (T value in values)
        {
            list.UniqueAdd(value);
        }
    }

    /// <summary>
    /// Adds the value to the list only if it does not already exist in the list. Uses list.Contains() to determine existence of previos values.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="list"></param>
    /// <param name="value"></param>
    public static void UniqueAdd<T>(this List<T> list, T value)
    {
        if (!list.Contains(value))
        {
            list.Add(value);
        }
    }
}

我在构建时收到以下错误:

CA0001 : Rule=Microsoft.Maintainability#CA1506, Target=Some.Namespace.ListExtensions : Collection was modified; enumeration operation may not execute.

这是错误的link,但我不确定如何根据这些信息修复我的扩展方法。它说

尝试重新设计类型或方法以减少与之耦合的类型数量。

有谁知道我为什么会收到此错误以及如何修复我的扩展方法以使其不违反此规则?

谢谢!

PS:之前有人提过,我已经考虑过使用HashSet,但是HashSet在compact框架中并不存在。

【问题讨论】:

    标签: c# list .net-3.5 extension-methods windows-ce


    【解决方案1】:

    我认为您的代码在 FxCop 中触发了一个错误,“集合已修改”是一个经典的 oops。然后它决定它的错误是你的问题,catch(Exception) 样式。

    寻找更新。我用的不抱怨你的代码(VS2010版本)。

    【讨论】:

    • 心理调试通常不受欢迎:(
    【解决方案2】:

    它告诉您在枚举列表时正在更改列表。从您的代码中可以清楚地看出这一点(您在枚举的同时添加到列表中)。

    怎么样:

    public static void UniqueAddRange<T>(this List<T> list, IEnumerable<T> values)
    {
        list.AddRange(values.Except(list));
    }
    

    或者,如果界面适合您的需要,请使用 Hashset。开箱即用,它可以满足您的需求。

    【讨论】:

    • 谢谢,我试试看。我忘记了 Contains 会无意中枚举列表,这就是我遇到此问题的原因。至于HashSet,我在帖子里提到过,它在compact框架中是不存在的。
    • 不,您看到此问题是因为UniqueAddRange 中的 foreach 循环正在迭代一个正在其脚下更改的枚举。发现了 Hashset 的东西,因此使用了删除线 ;) LINQ 方式应该也更快,因为它不必为每次插入检查整个列表。
    • 我不认为这是正确的:valueslist 是两个完全独立的列表,我只迭代 values,我从不修改它。我只修改list
    • 啊,是的。我的错。我现在应该去睡觉了,因为我没用!我敢说我提供的代码可能更有效。看起来@Hans 可能是对的。
    • 我不怀疑在完整的 .NET 框架中确实如此,但令人惊讶的是,紧凑的框架在使用 LINQ 时相当慢。
    猜你喜欢
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 1970-01-01
    相关资源
    最近更新 更多