Как обрабатывать массивы в устаревшем коде VB6 при переходе на .NET?

У меня есть задача перенести старый код VB6 в проект .NET. Все шло гладко с преобразованием старого кода в современный VB-диалект, пока я не столкнулся с проблемой индексации массивов. Старый код VB написан с учетом того, что все массивы начинаются с индекса 1, а массивы в .NET начинаются с 0.

Как мне с этим справиться?

  1. Переписать весь VB-код так, чтобы позиции предполагали индекс, начинающийся с нуля? (много изменений)

  2. Добавить нижнюю границу массива нулем (0)?

  3. Другое решение?


person Midas    schedule 23.08.2019    source источник
comment
Вы можете установить базовое число равным 1, используя объявление Option Base: https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/option-base-инструкция   -  person DBro    schedule 23.08.2019
comment
@DBro: Это работает для VB.NET?   -  person Midas    schedule 23.08.2019
comment
@Midas Нет, это не так.   -  person GSerg    schedule 23.08.2019
comment
О, это объявление больше не действует для VB.NET. Я не знал ... извините за ложную информацию. В этом случае правильный подход к этому - исправить код для использования индексов, отсчитываемых от нуля. У вас есть шанс внести ошибки, но технически, если оставить код как есть, вы тоже столкнетесь с потенциальными ошибками. Тем более, что вы продвигаетесь вперед с поддержанием кода.   -  person DBro    schedule 23.08.2019
comment
По правде говоря, я никогда не видел кода VB6, который предполагал бы любые границы массива как правильные. Есть lbound и ubound, их следует использовать. Я бы переписал старый код, чтобы использовать его везде, тогда он легко переносился.   -  person GSerg    schedule 23.08.2019
comment
@GSerg: Учитывая, что он полон сложных уравнений, это будет ад: | Но что поделаешь ... Придется попробовать кисловатый привкус мигрирующего VB.   -  person Midas    schedule 23.08.2019
comment
Если у вас есть многомерные массивы, .NET может создавать их с произвольной нижней границей, даже если это не отображается напрямую в языке (см. Документацию в System.Array). Вы можете сделать это даже для одномерных массивов, но это будет иметь проблемы с совместимостью, поскольку .NET обычно компилирует одномерные массивы в другой тип, который не поддерживает ненулевую нижнюю границу.   -  person Craig    schedule 23.08.2019
comment
Я бы рекомендовал в конечном итоге реализовать №1. Раньше я говорил о серьезной ошибке проектирования в .NET, связанной с установлением нижней границы 0, но почти 20 лет спустя они не собираются ее менять. Все остальное будет бороться с языком и средой выполнения и удивлять пользователей. (Помимо этого большого минуса, я думаю, вы обнаружите, что во многих других отношениях .NET VB - это огромный шаг вперед по сравнению с VB6.)   -  person Craig    schedule 23.08.2019
comment
(A) AFAICR, сторонние инструменты автоматического преобразования могут решить эту проблему за вас. Может быть, стоит попробовать, если у вас большая кодовая база и бюджет на их покупку. (B) Я уверен, что я также видел в Интернете код, который имитирует массивы на основе 1 в .Net, но я не могу найти его сейчас в Google. В основном простой класс с Dim и Redim методами и свойством по умолчанию Item, Lbound и Ubound. Вам нужно только изменить объявления массива, остальной код не изменится, включая те длинные уравнения, которые вы упомянули.   -  person MarkJ    schedule 23.08.2019
comment
PS плюс один, хороший вопрос, я не понимаю, почему кто-то проголосовал за закрытие.   -  person MarkJ    schedule 23.08.2019
comment
Хо, хм. Я вижу, что этот вопрос сейчас отложен. Я проголосовал за его повторное открытие. ИМХО, это хороший вопрос. Как бы то ни было, я являюсь ведущим пользователем StackOverflow в тегах VB6 и VB6-Migration (скромный кашель). @whoever проголосовал за закрытие вопроса: пожалуйста, оставьте комментарий, объяснив, почему это   -  person MarkJ    schedule 23.08.2019
comment
Что ж, я проголосовал за закрытие, поскольку в первую очередь основывался на мнении. Да, есть варианты: попробовать сделать на VB.NET 1 или попытаться переработать код, чтобы он основывался на 0. Я не думаю, что здесь есть что-то, что было бы действительно хорошим объективным ответом, это просто перечисление компромиссов. Я думаю, что этот тип вопросов на белой доске с разговорами о возможностях может быть лучше в программной инженерии, чем здесь.   -  person    schedule 23.08.2019
comment
Хотя все массивы в VB.NET имеют нижнюю границу нуля, выделение массива из n элементов приводит к n + 1 (от 0 до n) элементов. Если старый код предполагает индексацию от 1 до n, он все равно должен работать в VB.NET.   -  person R.J. Dunnill    schedule 30.08.2019


Ответы (1)


Я бы порекомендовал выбрать вариант 1 и найти время, чтобы преобразовать код во что-то похожее на .NET.

Вариант 2 также требует большой доработки (на первый взгляд более чем очевидной):

@GSerg: Если вы попробуете

Dim myArray As Int32()
ReDim myArray(10) 'creates an array with 11 elements (0..10), could be handy
For i As Int32 = LBound(myArray) To UBound(myArray) 'LBound is 0, UBound is 10
    Console.Out.WriteLine(i)
Next

вы получаете неправильный результат и вам нужно настроить свою логику, поскольку 11 элементов зациклены.

То же самое, если вы создадите такой массив:

Dim myArray(10) As Int32

Вам нужно будет заменить LBound на 1:

Dim myArray As Int32()
ReDim myArray(10) 'creates an array with 11 elements (0..10), could be handy
For i As Int32 = 1 To UBound(myArray) 'LBound is 0, UBound is 10
    Console.Out.WriteLine(i)
Next

Но поскольку вам все равно придется настраивать каждый массив, лучше выбрать вариант 1 ...

person Christoph    schedule 23.08.2019