Содержание
По мере изучения основ C# я пробую также переписать один из моих проектов с Delphi на C#. Пишу я пока без всяких изысков вроде визуального интерфейса, так как программа хоть и большая, но максимум, что пока от неё требуется — это собрать csv-файл из рассчитанных данных и визуализировать кое-какие моменты работы в Google Earth при помощи kml-файла. Когда я писал часть про логические операции, то мне понравилось использование выражения switch
вместо одноименной конструкции — коротко, понятно и лаконично. Однако , эта возможность доступна для использования только с версии C# 8.0, а у меня приложение разрабатывалось на .NET Framework 4.7.2 и C# 7.3, соответственно. А так как кода было написано уже достаточно много, то пришлось думать над тем, как перенести моё консольное приложение с .NET Framework 4.7.2 на NET Core 3.1.
Смена версий языка C# в Visual Studio 2019 не работает
Первое, что я предпринял для того, чтобы как можно более безболезненно сменить C# 7.3 на C# 8.0 — это попробовал изменить версию языка в Visual Studio. Судя по найденным на просторах Интернет инструкциям, делалось это через свойства проекта: надо было дважды кликнуть по Properties в обозревателе решений, затем, в открывшемся окне перейти на вкладку «Сборка», кликнуть кнопку «Дополнительно…» и, в открывшемся окне выбрать необходимую версию языка. Однако, в Visual Studio 2019 такой «фокус»не прошел:
Microsoft позаботился о том, чтобы разместить под неактивным списком выбора версии C# пояснение того, почему на данный момент нельзя сменить версию языка. Судя по полученной информации, компилятор C# последней версии определяет версию языка по умолчанию на основе целевой платформы или платформ проекта, интерфейс смены версии C# теперь не работает, а новые функции C# 8.0 поддерживаются только на .NET Core 3.x. Так что, чтобы «пощупать» новинки в C# 8.0 пришлось искать вариант того, как быстро мигрировать с .NET Framework 4.7.2 на NET Core 3.1.
Простой вариант переноса консольного приложения с .NET Framework 4.7.2 на NET Core 3.1
Вариант перехода с .NET Framework 4.7.2 на NET Core 3.1 нашелся относительно быстро на Хабре в блоге Microsoft (кто бы подумал), правда для консольного приложения пришлось его совсем чуточку доработать и добавить в этот вариант ещё один шаг. В конце этой статьи я приведу ссылку на первоисточник информации, чтобы соблюсти все правила цитирования.
Шаг 1. Запуск Portability Analyzer
Portability Analyzer — это небольшая утилита, которая анализирует код вашего проекта с целью выявления возможных проблем при переносе проекта на другую платформу. Скачать Portability Analyzer можно с вот этой странички.
Запускаем Portability Analyzer и указываем расположение исходного кода проекта:

После этого откроется файл Excel с отчётом по проверке. У меня этот файл выглядел следующим образом:

Оказалось, что используемая в моем проекте сборка SharpKml не на все 100% поддерживается в .NET Standard 1.2, но для .NET Core 3.1 подходит. Значит всё хорошо, можно переходить к следующему шагу. Если бы анализатор показал меньше 100% совместимости с .NET Core 3.1, то пришлось бы искать либо другую версию SharpKml или же искать альтернативу.
Шаг 2. Миграция .csproj в SDK-стиле
В Обозревателе решений необходимо кликнуть правой кнопкой мыши по своему проект и посмотреть есть ли в контекстном меню пункт «Изменить файл проекта». Вот так выглядит этот пункт в Visual Studio 2019:
А вот так будет выглядеть контекстное меню проекта без пункта:
Если пункт «Изменить файл проекта» имеется, то можно переходить к следующему шагу. Если же пункта нет, то делаем следующее:
- Смотрим, есть ли в проекта файл packages.config. В «Обозревателе решений» он выглядит вот так:
Если файл имеется, то кликаем на нем правой кнопкой мыши и выбираем пункт «Перенести packages.config в PackageReference…«:
Появится окно в котором необходимо нажать «Ok»
2. Выгружаем проект. Для этого кликаем по названию проекта правой кнопкой мыши и выбираем пункт «Выгрузить проект»
После выгрузки проект в «Обозревателе решений» будет выглядеть вот так:
Снова кликаем по названию проекта правой кнопкой мыши и выбираем пункт «Изменить название_проекта.cproj«. В моем случае этот пункт выглядел вот так:
Откроется XML-файл примерно такого содержания:
Содержимое этого файла необходимо скопировать в «Блокнот». Теперь необходимо удалить всё из файла в Visual Studio. Согласен с автором первоисточника данной инструкции, что звучит такой пункт, мягко говоря, угрожающе. Но, на деле, ничего страшного не произойдет. Удаляйте — не переживайте (копия лежит в «Блокноте»).
Вместо только что удаленного текста вставьте следующий код необходимый для консольного приложения(здесь небольшое расхождение с первоисточником):
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.1</TargetFramework> </PropertyGroup> </Project>
Теперь переходим в Блокнот и ищем там строку PackageReference. Если ничего не нашли — двигаемся дальше. Если нашли PackageReference, то копируем весь узел ItemGroup, содержащий PackageReference, в файл проекта, открытого в Visual Studio. Вставлять скопированный текст необходимо перед закрывающим тегом </Project>
, а не в конец файла, как это было сказано в первоисточнике. Скопированный блок должен выглядеть так:
<ItemGroup> <PackageReference Include="SharpKml.Core"> <Version>5.1.2</Version> </PackageReference> <PackageReference Include="System.Runtime.WindowsRuntime" Version="4.7.0" /> </ItemGroup>
У меня такой блок оказался всего один, поэтом итоговый файл *.cproj стал выглядеть вот так:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.1</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="SharpKml.Core"> <Version>5.1.2</Version> </PackageReference> </ItemGroup> </Project>
Теперь делаем то же самое, что и выше, но только для ProjectReference. Нашли ProjectReference — копируем весь ItemGroup в конец файла перед закрывающим тегом </Project>
. У меня в Блокноте таких строк не оказалось, поэтому я перешел к следующему шагу — сохраняем все и перезагружаем проект кликнув правой кнопкой мыши по названию проекта и выбрав пункт «Перезагрузить проект». Теперь наш проект в «Обозревателе решений» стал выглядеть немного по другому:
В принципе, на этом переход с .NET Framework 4.7.2 на NET Core 3.1 закончен — можно попробовать запустить проект и убедиться, что все работает. Однако у меня при попытке запуска приложения посыпались ошибки вида:
Помогло удаление файла AssemblyInfo.cs
После этого проект запустился, работоспособность не нарушилась. Однако встретилась другая проблема.
Использование System.Windows в .NET Core
До перехода на .NET Core для работы с координатами точек, полигонами и так далее я использовал стандартные классы Windows из пространства имен System.Windows (добавив предварительно ссылку в Зависимости). Однако, в .NET Core Visual Studio «ругнулась» на то, что в этом пространстве имен классов типа Point
и Rect
не существует и пометила using System.Windows
серым цветом с предложением удалить неиспользуемые директивы:
Решение нашлось на StackOverflow. Для того, чтобы использовать стандартные примитивы из Windows типа Point и Rect для приложения на .NET Core 3.x необходимо установить пакет System.Runtime.WindowsRuntime
через менеджер пакетов NuGet. Для этого кликаем по названию проекта правой кнопкой мыши и выбираем пункт «Управление пакетами NuGet»
В окне менеджера пакетов переходим на вкладку «Обзор» и забиваем в строку поиска System.Runtime.WindowsRuntime
.
Жмем кнопку установить и ждем пока NuGet установит пакет. После установки пакета проект в «Обозревателе решений» станет выглядеть вот так:
Теперь необходимо добавить в проект пространство имен:
using Windows.Foundation;
И можно пользоваться классами Point
и Rect
:
Вот так простое человеческое желание использовать в работе новейшие возможности языка C# привели к переносу проекта c .NET Framework 4.7.2 на NET Core 3.1. Надеюсь, что вам эта небольшая инструкция пригодиться.
Источники информации:
- Статья на Хабре: Перенос десктопных приложений на .NET Core
- StackOverflow: Using System.Windows in .NET Core