в какой ситуации элемент System.Collections.Generic.List не будет успешно удален? - PullRequest
13 голосов
/ 20 мая 2011

В какой ситуации элемент System.Collections.Generic.List не будет успешно удален?

С http://msdn.microsoft.com/en-us/library/cd666k3e.aspx:

true, если элемент успешно удален; иначе ложно. Этот метод также возвращает false, если элемент не был найден в Список (Т).

То, как они формулируют это, заставляет меня думать, что вполне возможно, что операция удаления для элемента, найденного в Списке (Of T), может действительно завершиться неудачей, отсюда и этот вопрос.

Ответы [ 4 ]

5 голосов
/ 20 мая 2011

Если посмотреть на источник System.Collections.Generic.List в Reflector, то окажется, что элемент, который не найден в коллекции, действительно является единственным способом удаления, возвращающим значение false.

int index = this.IndexOf(item);
if (index >= 0)
{
    this.RemoveAt(index);
    return true;
}
return false;
4 голосов
/ 20 мая 2011
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public bool Remove(T item)
{
    int index = this.IndexOf(item);
    if (index >= 0)
    {
        this.RemoveAt(index);
        return true;
    }
    return false;
}

Код выше через отражатель.Только не будет удален, если его не было в коллекции.Я предполагаю несоответствие документации / языка.

4 голосов
/ 20 мая 2011

Да, может, если вы пытаетесь удалить элемент, которого нет в списке - он классифицируется как сбой и возвращает false, чтобы показать вам, что ничего не было удалено.

Это может быть полезно, если вы затем захотите сделать другой код, если что-то действительно было удалено.

Обновление: , если ваш класс реализует IEquality, и это вызывает исключение, код разрешает выполнение броска, так как в нем нет возможности вернуться.

В сочетании с другими, публикующими отраженный источник, возвращение false происходит только тогда, когда не удается найти элемент.

Обновление: дальше к источнику других людей. Если вы посмотрите на цепочку методов IndexOf, вы увидите, что она сводится к равенству и ничего особенного не делает.

List.Remove:

public bool Remove(T item)
{
    int num = this.IndexOf(item);
    if (num >= 0)
    {
        this.RemoveAt(num);
        return true;
    }
    return false;
}

List.IndexOf:

public int IndexOf(T item)
{
    return Array.IndexOf<T>(this._items, item, 0, this._size);
}

Array.indexOf:

public static int IndexOf<T>(T[] array, T value, int startIndex, int count)
{
    if (array == null)
    {
        throw new ArgumentNullException("array");
    }
    if (startIndex < 0 || startIndex > array.Length)
    {
        throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
    }
    if (count < 0 || count > array.Length - startIndex)
    {
        throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
    }
    return EqualityComparer<T>.Default.IndexOf(array, value, startIndex, count);
}

EqualityComparer.IndexOf:

internal virtual int IndexOf(T[] array, T value, int startIndex, int count)
{
    int num = startIndex + count;
    for (int i = startIndex; i < num; i++)
    {
        if (this.Equals(array[i], value))
        {
            return i;
        }
    }
    return -1;
}

Весь код от ILSpy, нет благодаря Red Gate: -)

2 голосов
/ 20 мая 2011

В исходном коде Mono для сравнения:

https://github.com/mono/mono/raw/master/mcs/class/corlib/System.Collections.Generic/List.cs

public bool Remove (T item)
{
    int loc = IndexOf (item);
    if (loc != -1)
        RemoveAt (loc);

    return loc != -1;
}

Итак, документация слишком нечеткая

...