В какой ситуации элемент в System.Collections.Generic.List не будет удален успешно?
в какой ситуации элемент в System.Collections.Generic.List не будет удален успешно?
Из http://msdn.microsoft.com/en-us/library/cd666k3e.aspx:
true, если элемент успешно удален; в противном случае - false. Этот метод также возвращает false, если элемент не найден в Список (Of T).
То, как они выражают это, заставляет меня думать, что возможно, что операция Remove на элементе, найденном в List (Of T), может действительно потерпеть неудачу, следовательно, этот вопрос.
Ответы
Ответ 1
Глядя на источник System.Collections.Generic.List в Reflector, кажется, что элемент, который не найден в коллекции, действительно является единственным способом Remove для возврата false.
int index = this.IndexOf(item);
if (index >= 0)
{
this.RemoveAt(index);
return true;
}
return false;
Ответ 2
Да, если вы пытаетесь удалить элемент, который отсутствует в списке, он классифицируется как сбой и возвращает false, чтобы показать вам, что ничего не было удалено.
Это может быть полезно, если вы хотите сделать другой код, если что-то действительно было удалено.
Обновление:, если ваш класс реализует IEquality и генерирует исключение, код позволяет запустить throw, поскольку в нем нет возможности вернуться.
В сочетании с другими, отправляющими отраженный источник, возврат 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: -)
Ответ 3
[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
В исходном коде 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;
}
Итак, документация чрезмерно нечеткая