#c# #.net #vb.net #list #generic-list
#c# #.net #vb.net #Список #generic-list
Вопрос:
в какой ситуации элемент в System . Collections . Generic . List не будет успешно удален?Коллекции.Универсальный.Список не будет успешно удален?
Из http://msdn.microsoft.com/en-us/library/cd666k3e.aspx:
значение true, если элемент успешно удален; в противном случае значение false. Этот метод также возвращает false, если элемент не был найден в списке (из T).
То, как они формулируют это, заставляет меня думать, что возможно, что операция удаления элемента, найденного в списке (из T), действительно может завершиться неудачей, отсюда и этот вопрос.
Комментарии:
1. Я понимаю, что это сбой, если элемент не был найден, но мне также интересно, как еще это может привести к сбою… Хороший вопрос 🙂
Ответ №1:
Смотрим на систему.Коллекции.Универсальный.Источник списка в Reflector, похоже, что элемент, не найденный в коллекции, действительно является единственным способом для Remove вернуть false .
int index = this.IndexOf(item);
if (index >= 0)
{
this.RemoveAt(index);
return true;
}
return false;
Ответ №2:
[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;
}
Приведенный выше код с помощью reflector. Не будет удален, только если его не было в коллекции. Я предполагаю, что несоответствие документации / языка.
Ответ №3:
Да, это возможно, если вы пытаетесь удалить элемент, которого нет в списке — он классифицируется как сбой и возвращает 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;
}
Список.indexOf:
public int IndexOf(T item)
{
return Array.IndexOf<T>(this._items, item, 0, this._size);
}
Массив.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 🙂
Комментарии:
1. В цитируемых документах MSDN указано, что он возвращает false, если элемент не был найден в списке, а также если он не был успешно удален…
Ответ №4:
В исходном коде Mono для сравнения:
https://github.com/mono/mono/raw/master/mcs/class/corlib/System.Коллекции.Generic/List.cs
public bool Remove (T item)
{
int loc = IndexOf (item);
if (loc != -1)
RemoveAt (loc);
return loc != -1;
}
Итак, документация слишком нечеткая