[Из песочницы] Избавляемся от Visual Basic

image

Вот и настал тот переломный момент, когда мы решили перевести два проекта с VB на С#. Кому интересно — прошу под кат.

Введение


Данные проекты нам достались от подрядческой организации, которая писала их на протяжении лет 5–6. В общей сложности это около 1,5 млн. строк кода, если верить средству оценки метрик в Visual Studio, из которых около 30% на C#, а остальное на VB. Почему мы решили это сделать?! Скорее всего из-за нежелания работать с VB и отсутствия хороших vb-разработчиков.

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

Подготовка


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

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

Почему относительно?! Да потому, что после конвертации, в любом случае, имеется нотка неизвестного поведения программы. Это может всплыть сразу, если у вас код не покрыт 100% тестами. В нашем случае, я про тесты вообще промолчу, ибо нет их вовсе. Ну что ж — рассмотрим, что за шаги мы выделили:

1) Выбор инструмента для конвертации

Это очень важный этап на таком нелегком пути, ведь от того какую пилу выберешь, будет зависеть скорость и качество распила. После многочисленных вопросов гуглу и совещаний, мы остановились на двух продуктах: Instant CSharp и SharpDevelop версии 4.х (в версии 5.х конвертация не поддерживается), что очень странное, на мой взгляд, решение.

SharpDevelop бесплатен — это несомненно плюс, но и Instant CSharp имеет free версию, которая не отличается функциональностью от платной версии, лишь имеется ограничение на число строк в конвертируемом проекте. Плюсом Instant CSharp является то, что он лучше конвертирует WinForms. Есть у него и минус — это корректная конвертация только UTF файлов.

Решили использовать Instant CSharp для мелких проектов, а SharpDevelop для всего остального.

2) Составление списка VB проектов и формирование диаграммы зависимостей

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

image

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

3) Замена ReDim на Array.Resize ()

Был написан небольшой класс Re, чтобы реализовать данную замену.

Public Class Re
    Public Shared Sub [Dim](Of T)(ByRef Source As T(), HighBound As Integer)
        //изменяем размер массива
        DimPreserve(Source, HighBound)
        //очищаем массив
        Array.Clear(Source, 0, HighBound + 1)
    End Sub

    Public Shared Sub DimPreserve(Of T)(ByRef Source As T(), HighBound As Integer)
        //изменяем размер массива
        Array.Resize(Source, HighBound + 1)
    End Sub
End Class



Далее все вызовы ReDim Preserve X (N) заменили на Re.DimPreserve (X, N), а ReDim X (N) заменили на Re.Dim (X, N).

4) Включение опции компиляции strict

По умолчанию .NET Visual Basic или компилятор Visual Basic не обеспечивает строгую типизацию. Чтобы изменить это поведение по умолчанию, необходимо в свойствах проекта на вкладке Compile установить Option strict в значение on. После этого исправить все возникшие ошибки.

Следующие пункты не требуют разъяснений, так как они просты и понятны. Мы просто берем в руки ReSharper и выполняем все, описанные ниже пункты, со скоростью звука (а то и еще быстрее).

5) Для value type переменных заменить Nothing на Default
6) Замена And на AndAlso и Or на OrElse
7) Удаление конструкций Imports, ссылающихся на классы
8) Замена вызова метода вида .Method на .Method ()
9) Удаление конструкций Exit Try
10) Замена сравнения строковых переменных с Nothing или » или со String.Empty на String.IsNullOrEmpty ()
11) Замена ненужных директив ByRef на ByVal у параметров методов
12) Переименование методов, имеющих имя своего же класса
13) Исправление некорректных регистронезависимых вызовов в VB коде

Конвертация


И вот мы подошли к завершающему этапу — этапу конвертации. Инструмент выбран, проекты подготовлены и ждут своей участи.

Что ж — начнем!

Процесс конвертации не сложнее программы «Hello World», только требует немного большего времени. Приведу небольшой tutorial, как это делается в SharpDevelop и Instant CSharp.

Конвертация с помощью SharpDevelop

1. Скопировать проект VB.NET в отдельную папку
2. Открыть проект в SharpDevelop (File→Open→Project/Solution)
3. Сконвертировать проект (Project→Convert→From VB.NET to C#)
4. Открыть в Visual Studio основной солюшен и удалить проект VB.NET
5. Удалить папку с проектом VB.NET
6. Переименовать папку и файл сконвертированного в C# проекта (убрать слово Converted)
7. Скопировать папку с новым проектом в каталог с основным солюшеном
8. Добавить в солюшен скопированный проект
9. Добавить ссылки на новый проект (C#) во все остальный проекты, в которых были ссылки на старый (VB.NET). Для этого можно воспользоваться средством системы управления версиями для просмотра изменений в файлах *.csproj и *.vbproj
10. Попробовать скомпилировать проект. Исправить возникающие ошибки


Конвертация с помощью Instant CSharp
Instant CSharp не дружит с ANSI, так что необходимо сначала преобразовать кодировку файлов исходников в UTF8.
Удобная утилитка UTFCast Express
1. Открыть UTFCast Express
2. В поле Source directory указать путь к каталогу проекта
3. В поле Target directory указать путь к каталогу в который будут перемещены файлы проекта в кодировке UTF8
4. Выстовить опцию Copy unconverted и запустить преобразование

И после этих танцев с бубном можно производить конвертацию проекта.


1. Открыть Instant CSharp
2. В поле VB project or solution: указать путь к файлу проекта *.vbproj
3. В поле C# target folder: указать каталог, в который будет сохранён сконвертированный в C# проект
4. Сконвертировать проект (Project→Convert→From VB.NET to C#)
5. Открыть в Visual Studio основной солюшен и удалить проект VB.NET
6. Удалить папку с проектом VB.NET
7. Скопировать папку с новым проектом в каталог с основным солюшеном
8. Добавить в солюшен скопированный проект
9. Добавить ссылки на новый проект (C#) во все остальный проекты, в которых были ссылки на старый (VB.NET). Для этого можно воспользоваться средством системы управления версиями для просмотра изменений в файлах *.csproj и *.vbproj
10. Попробовать скомпилировать проект. Исправить возникающие ошибки


Вывод


В итоге мы перевели оба наших проекта полностью на c#.Сейчас идет, полным ходом, рефакторинг кода, кстати, не в рекламу будет сказано, но ReSharper в этом деле не заменим. В процессе эксплуатации, иногда, всплывают ошибки, связанные с конвертацией, но это неизбежно, увы.

Надеюсь, наш небольшой опыт будет полезен и вам, уважаемые хабражители.

Ссылки


Instant CSharp
SharpDevelop

© Habrahabr.ru