Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16139 / 11263 / 2888
Регистрация: 21.04.2018
Сообщений: 33,108
Записей в блоге: 2

Array.IndexOf(Array, Object, Int32) не получаю исключение, если startIndex = array.Length

01.07.2025, 23:12. Показов 1320. Ответов 7

Студворк — интернет-сервис помощи студентам
Может гоню уже на старости лет...

Array.IndexOf(Array, Object, Int32)
Исключения:
ArgumentOutOfRangeException
startIndex находится вне диапазона допустимых индексов для array.
Пример:
C#
1
2
3
    int[] arr = new int[] { 1, 2, 3}; // допустимые индексы 0, 1, 2
    int i = Array.IndexOf(arr, 1, 3); // startIndex = 3 - это не допустимый индекс.
    Console.WriteLine(i);
Ожидание: IndexOf должен выдать исключение.
Реальность: работает без исключения и возвращает -1.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
01.07.2025, 23:12
Ответы с готовыми решениями:

Метод Graphics.DrawLine(Int32, Int32, Int32, Int32) Узнать координаты всех точек данной прямой
Как я могу получить координаты всех точек, создаваемых данных методом? Мне необходимо это в...

Значение StartIndex не может быть меньше нуля. Имя параметра: startIndex. Смена раскладки с английской на русскую
Пытаюсь сменить текст, введенный на английской раскладке на русскую. То есть, когда если написали...

Метод Socket.Receive(Byte[], Int32, Int32, SocketFlags) отрабатывает некорректно
Пишу передачу файлов с помощью TCP сокетов. Когда казалось уже всё готово..при тестирование в...

7
Администратор
Эксперт .NET
 Аватар для OwenGlendower
18295 / 14219 / 5368
Регистрация: 17.03.2014
Сообщений: 28,896
Записей в блоге: 1
02.07.2025, 00:24
Лучший ответ Сообщение было отмечено Элд Хасп как решение

Решение

Элд Хасп, startIndex может быть равен длине массива т.к. иначе мы бы не смогли искать в пустом массиве.
1
Эксперт .NET
 Аватар для Usaga
14297 / 9382 / 1353
Регистрация: 21.01.2016
Сообщений: 35,371
02.07.2025, 02:46
Лучший ответ Сообщение было отмечено Элд Хасп как решение

Решение

Элд Хасп, из этой же самой документации по ссылке (см. комментарии под примером кода):

Если startIndex равно Array.Length, метод возвращает значение -1. Если startIndex значение больше Array.Length, метод создает исключение ArgumentOutOfRangeException.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16139 / 11263 / 2888
Регистрация: 21.04.2018
Сообщений: 33,108
Записей в блоге: 2
02.07.2025, 11:17  [ТС]
Цитата Сообщение от OwenGlendower Посмотреть сообщение
startIndex может быть равен длине массива т.к. иначе мы бы не смогли искать в пустом массиве.
Ну, мне как-то это не кажется слишком логичным.
Я просто сделал (давно уже) метод расширения IndexOf(this IList list, value, startIndex, count) и несколько его перегрузок.
Там реализовал, как описал в начале.

А недавно выяснилось, что поведение моего метода отличается от дефолтного.
Это меня и удивило.

Искать в пустом массиве перегрузкой IndexOf(this IList list, predicate, startIndex, count), как я думал, в принципе не верно и такая перегрузка всегда должна давать исключение.
А перегрузка IndexOf(this IList list, predicate) пустой массив у меня нормально "переваривала".

Цитата Сообщение от Usaga Посмотреть сообщение
из этой же самой документации по ссылке (см. комментарии под примером кода):
А коммент, то я и проморгал...
Разъяснение в документации теперь понятно.
Свой метод, конечно переделаю под аналогичное поведение, но некое ощущение какой-то неправильности, несуразности осталось
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
02.07.2025, 17:20
Цитата Сообщение от Элд Хасп Посмотреть сообщение
некое ощущение какой-то неправильности, несуразности осталось
ИМХО, но кажись не критично. Вызов поиска для array начиная с length позиции это то что нужно провалидировать ДО попыток обращения к методу, а не полагаться что метод вернёт что-то там. Может я не прав, но логика такого плана

C#
1
2
3
4
if(startIndex < length && length > 0)
    index = array.indexOf(startIndex, predicate);
else
    index = -1;
Более очевидна и читаема, чем просто index = array.IndexOf(startIndex, predicate). Понятное дело что лепить проверки на каждый чих не удобно и не логично, но как по мне также не логичным в принципе пытаться искать за пределами массива и рассчитывать на какой-то там результат. Поэтому если есть основания полагать что startIndex вылетит за диапазон, то это задача в первую очередь для верхнего уровня кода.

Как я понял, такое "разночтение" что для startIndex == array.Length и startIndex > array.Length добавили чтобы было проще писать всякие алгоритмы, где исходный массив делят на подмассивы, и приходится очень много где лепить проверки для пустых массивов (как ранее упомянул OwenGlendower). Т.е. авторы поступили в лучших традициях MS, поставив во главу практичность, а не "правильность".
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16139 / 11263 / 2888
Регистрация: 21.04.2018
Сообщений: 33,108
Записей в блоге: 2
02.07.2025, 19:13  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
приходится очень много где лепить проверки для пустых массивов (как ранее упомянул OwenGlendower)
Не совсем так.

Для массива { 1, 2, 3}
Проверка пустого массива в полной перегрузке это IndexOf(2, 1, 0). Здесь и не должно быть исключения.
А вот почему при выходе за границы диапазона IndexOf(2, 3, 0) нет исключения.... в мою логику не укладывается.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
02.07.2025, 20:34
Ну, лично я решаю 146% своих задач с помощью Linq, так что быстро классный пример для этого не подгоню. Всё что приходит на ум, это такой пример со string (не совсем наш метод, но логика поведения ровно такая же)

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Text;
 
var buff = "<a href=\"";
var startMarker = "<a href=\"";
var endMarker = '\"';
var startIndex = buff.IndexOf(startMarker);
startIndex += startMarker.Length;
var endIndex = buff.IndexOf(endMarker, startIndex);
var builder = new StringBuilder();
while (endIndex == -1)
{
    builder.AppendLine(buff.Substring(startIndex));
    buff = Console.ReadLine()!;
    startIndex = 0;
    endIndex = buff.IndexOf(endMarker);
}
builder.AppendLine(buff.Substring(startIndex, endIndex - startIndex));
;
Если предположить что у нас IndexOf будет кидать исключение в любом случае, то код несколько усложняется
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System.Text;
 
var buff = "<a href=\"";
var startMarker = "<a href=\"";
var endMarker = '\"';
var startIndex = buff.IndexOf(startMarker);
startIndex += startMarker.Length;
var builder = new StringBuilder();
var endIndex = -1;
if(startIndex < buff.Length) // добавляется первая проверка что мы не достигли конца буфера сразу
    buff.IndexOf(endMarker, startIndex);
while (endIndex == -1)
{
    builder.AppendLine(buff.Substring(startIndex));
    buff = Console.ReadLine()!;
    startIndex = 0;
    if(buff.Length > 0) // нам может прилететь пустая строка, что не означает конец потока и валидное значение которое просто нужно скипнуть
        endIndex = buff.IndexOf(endMarker);
}
builder.AppendLine(buff.Substring(startIndex, endIndex - startIndex));
Вроде как и не смертельно, но менее удобное, чем текущая реализация IndexOf.

--------------------------------------------------

Чуть абстрагируемся:
- мы блоками грузим данные в массив-буфер
- мы ищем в массиве данные поочерёдно -- сначала А, потом В, и только потом С.
- при нахождении каждого элемента нам нужно зафиксировать его позицию и сделать +1 для следующего поиска.
- этот +1 сразу может выходить за текущий буфер.
- при этом мы на 146% уверенны что прогрузим следующий блок и можем стартовать поиск в нём.
- опционально следующий блок может быть Length = 0, что означает что просто нужно брать следующий

Замечу что выход startIndex > length скорее всего будет означать что мы где-то налажали в алгоритме в принципе. Не уверен на 100% в этом утверждении, но внутренняя чуйка подсказывает что это так.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16139 / 11263 / 2888
Регистрация: 21.04.2018
Сообщений: 33,108
Записей в блоге: 2
02.07.2025, 21:34  [ТС]
Wolfdp, Ну, это скорее о необходимости вообще исключений в этом методе.
Убери все исключения и ваш метод так же будет работать.

То есть для примера нужен код выполняющий условия:
1) Исключение при startIndex == аrray.Length - мешают;
2) Исключение при startIndex > аrray.Length - помогают.

Добавлено через 1 минуту
Такие задачи исключительно реки, я думаю.
Это одна из причин почему я натолкнулся на это случайно после нескольких лет использования своего метода.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
02.07.2025, 21:34
Помогаю со студенческими работами здесь

Конвертировать String в struct (например, string "System.Int32" в struct System.Int32)
Всем привет и здоровья! Столкнулся с некой проблемой. Мне нужно как-то конвертировать string в...

В чем разница данных методов IndexOf и IndexOf<>
Доброго времени суток. Подскажите пожалуйста в чем отличие методов с символами &lt;&gt; и без них ?

Значения startIndex указателя и длины не указывают на действительную строку
Помогите пожалуйста! на это: this-&gt;textBox2-&gt;Text += gcnew System::String(str) + &quot;\r\n&quot;; ругается...

Ошибка "startIndex должен быть меньше, чем длина строки."
Доброго времени суток! Задача такая: &quot;Достать из файла координаты x,y и z, преобразовать в некую...

Ошибка "startIndex должен быть меньше, чем длина строки."
Привет всем! Появилось вот эта вот ошибка, не могу её устранить &quot; Ошибка &quot;startIndex должен быть...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru