File Scoped Namespaces aus C# 10 in einem .NET-Framework-4.8-Projekt verwenden

Ich wollte ein bestehendes Projekt (Klassenbibliothek) mit dem Full .NET Framework 4.8 auf File Scoped Namespaces umstellen.

Also dass so etwas:

namespace MyProject 
{
    public sealed MyClass { }
}

auch so geschrieben werden kann:

namespace MyProject;

public sealed MyClass { }

Dazu habe ich eine Datei „Directory.Build.props“ mit folgendem Inhalt in denselben Ordner wie die CSPROJ-Datei gelegt:

<Project>
 <PropertyGroup>
   <LangVersion>preview</LangVersion>
 </PropertyGroup>
</Project>

Doch er hat immer beim Kompilieren des Projekts gemeckert, dass ihm die Klammern { und } bei der Namespace-Deklaration fehlen.

Dann habe ich zum Spaß mit VS 2022 ein komplett neues Klassenbibliotheks-Projekt mit obiger „Directory.Build.props“-Datei erstellt.

Und dieses Projekt wurde korrekt kompiliert.

Ich war verwirrt.

Dann habe ich die beiden CSPROJ-Dateien verglichen, und herausgefunden, dass im Projekt, das fehlerhaft kompiliert, „Microsoft.Net.Compilers.Toolset“ als NuGet-Paket referenziert war, bei dem Projekt, das korrekt kompiliert, nicht.

Konkret fing die fehlerhaft kompilierende CSPROJ-Projektdatei so an:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <Import Project="..\packages\Microsoft.Net.Compilers.Toolset.3.11.0\build\Microsoft.Net.Compilers.Toolset.props" Condition="Exists('..\packages\Microsoft.Net.Compilers.Toolset.3.11.0\build\Microsoft.Net.Compilers.Toolset.props')" />
  <PropertyGroup>

Und die korrekt kompilierende CSPROJ-Datei so:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>

Lösung

Ich habe dann zunächst über die VS-2022-GUI das NuGet-Paket „Microsoft.Net.Compilers.Toolset“ deinstalliert.

Dann hat das Projekt auch korrekt kompiliert.

Ich bin zurzeit noch am Überlegen, ob ich diese Zeile manuell in die CSPROJ-Datei oben einfügen sollte:

<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />

Diese war im neuen Projekt auch enthalten, mir ist nicht ganz klar, was die genau macht. Eventuell hole ich das später noch nach.

Hier gibt es eine Erklärung, was die importierte Datei „Microsoft.Common.props“ macht.

Es gab dann noch ein ganz altes Projekt (Typ „Website“), noch mit Code im Ordner „App_Code“, das musste dann auch erst nach „Webprojekt“ migriert werden, bevor die neuen Features funktioniert haben.