Тестирование C# 9.0 в VS2019 - CS0518 IsExternalInit не определен и не импортирован ... Как его определить / импортировать?

C# 9.0 все еще находится в стадии разработки. Есть пара ссылок, которые наводят меня на мысль, что теперь это должно быть проверено (по крайней мере, некоторые из них).

  1. Блог Microsoft, написанный самим мистером Awesome, в котором представлены функции. https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/
  2. Страница отслеживания языка на github: https://github.com/dotnet/roslyn/blob/master/docs/Language%20Feature%20Status.md

Я использую VS 2019 16.7 Preview 3.1. Я выбрал языковую версию для предварительного просмотра проекта.

Некоторые возможности C# 9, которые я могу использовать. Подобно:Dictionary<string, object> Stuff = new()

Но используя новый init функция дает мне эту ошибку: Error CS0518 Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported

Как это исправить?

Примеры кода, вызывающего ошибку:

class Test
{
   public int Hello { get; init; }
}

а также

record Test(int hello);

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

На странице отслеживания языка, на которую я ссылался выше, говорится, что эта функция была Merged into 16.7p3, который я использую.

Я просто слишком взволнован? Мне нужно ждать? Или есть способ поиграть с этими функциями прямо сейчас:D

РЕДАКТИРОВАТЬ (запрашивается в комментариях) - Добавление csproj для консольного приложения.net 5.0:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>
</Project>

РЕДАКТИРОВАТЬ #2: обходной путь размещен здесь - https://github.com/dotnet/roslyn/issues/45510

4 ответа

Решение

Это ошибка в текущей предварительной версии и последней основной ветке (27 июня). Простая запись в https://sharplab.io/ создает ту же ошибку.

Просто добавьте недостающий тип где-нибудь в вашем проекте

namespace System.Runtime.CompilerServices
{
    public class IsExternalInit{}
}

Записи и init будет работать без проблем.

Только LinqPad 6 работает без проблем, вероятно, потому, что он тоже включает этот тип

Если вы не любите засорять каждый проект IsExternalInit класс, вы можете использовать Directory.Build.props чтобы автоматически добавить файл как невидимый элемент компиляции:

      <?xml version="1.0" encoding="utf-8"?>
<Project>
    <ItemGroup>
        <Compile Include="$(MSBuildThisFileDirectory)IsExternalInit.cs" Visible="false" />
    </ItemGroup>
</Project>

Добавьте / отредактируйте этот файл в корне вашего решения и добавьте IsExternalInit.csфайл и здесь. Это автоматически добавит этот файл во все ваши проекты.

Заимствуя у Панайотиса Канавоса, вы можете фактически объявить IsExternalInit как запись (самоисполняющееся пророчество):

      namespace System.Runtime.CompilerServices
{
    public record IsExternalInit;
}

Хороший ответ @Brouke, я просто объясню подробнее:

1 - В корневой папке (папке решения) создайте файл с именем Directory.Build.propsкуда *.prosявляется его продолжением.

2 - Отредактируйте этот файл и добавьте:

      <?xml version="1.0" encoding="utf-8"?>
<Project>
    <ItemGroup>
        <Compile Include="$(MSBuildThisFileDirectory)IsExternalInit.cs" Visible="false" />
    </ItemGroup>
</Project>

3 - Добавьте файл вместе с:

      using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    public record IsExternalInit;
}

4 - Удалить все остальные IsExternalInit.csфайлы, перестройте решение и перезапустите VS.

Другие вопросы по тегам