C #: EinfĂĽhrung in Quellcode-Generatoren

Bild


Wir freuen uns, Ihnen eine Vorschau der Quellcode-Generatoren präsentieren zu können. Dies ist eine neue Funktion, mit der C # -Entwickler benutzerdefinierten Code analysieren und neue C # -Dateien erstellen können, die wiederum zum Kompilierungsprozess hinzugefügt werden können. Dies geschieht mit Hilfe einer neuen Komponente - dem Source Generator.


Um mit Generatoren beginnen zu können, benötigen Sie die neueste Vorschau von .NET 5 und Visual Studio . Hinweis: Visual Studio ist erforderlich, um den Quellcodegenerator zu erstellen. Dies wird in der nächsten Vorschau von .NET 5 geändert.


Was ist ein Quellcodegenerator?


Ein Quellcodegenerator ist ein Code, der während der Kompilierung ausgeführt wird, das Programm überprüft und zusätzliche Dateien erstellt, die dann mit dem Rest des Codes kompiliert werden.


Hier sind zwei Hauptfunktionen, die Sie implementieren können:


  • Rufen Sie ein Kompilierungsobjekt ab, das den gesamten kompilierten Benutzercode darstellt. Dieses Objekt kann analysiert werden, und Sie können Code schreiben, der mit syntaktischen und semantischen Modellen von kompiliertem Code funktioniert, wie dies bei modernen Analysatoren der Fall ist.
  • C# , . , .

. , , C# . Roslyn, , C#.


:


Bild


.NET Standard 2.0, , .NET Standard.


, .


, .


— , , , .


: , IL (IL weaving) MSBuild. .


— .NET. . .


, ASP.NET Core - , , razor . , : - , , , , . , .


— . .


, . MSBuild C# ( CSC) . , . MSBuild, , .


, — "-" (“stringly-typed”) API. , , ASP.NET Core razor. . , , .


API . -, .


Ahead-of-Time (AOT)


linker-based AOT-. , System.Text.Json, System.Text.RegularExpressions; ASP.NET Core WPF, / .


NuGet . .NET, "" ( “linkability”) AOT . OSS , .NET.


Hello World-


, .


, “Hello World” , . :


public class SomeClassInMyCode
{
    public void SomeMethodIHave()
    {
        HelloWorldGenerated.HelloWorld.SayHello(); 
        //  Console.WriteLine("Hello World!")     
    }
}

, :


1. .NET.


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>

  <PropertyGroup>
    <RestoreAdditionalProjectSources>https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json ;$(RestoreAdditionalProjectSources)</RestoreAdditionalProjectSources>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.6.0-3.20207.2" PrivateAssets="all" />
    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.0.0-beta2.final" PrivateAssets="all" />
  </ItemGroup>

</Project>

2. C#, .


using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace MyGenerator
{
    [Generator]
    public class MySourceGenerator : ISourceGenerator
    {
        public void Execute(SourceGeneratorContext context)
        {
            // TODO -     
        }

        public void Initialize(InitializationContext context)
        {
             //     
        }
    }
}

Microsoft.CodeAnalysis.Generator Microsoft.CodeAnalysis.ISourceGenerator.


3. .


using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;

namespace SourceGeneratorSamples
{
    [Generator]
    public class HelloWorldGenerator : ISourceGenerator
    {
        public void Execute(SourceGeneratorContext context)
        {

            // ,       
            var sourceBuilder = new StringBuilder(@"

using System;
namespace HelloWorldGenerated
{
    public static class HelloWorld
    {
        public static void SayHello() 
        {
            Console.WriteLine(""   !"");
            Console.WriteLine(""       "");
");

           //  ,       
            var syntaxTrees = context.Compilation.SyntaxTrees;
            //        ,   
            foreach (SyntaxTree tree in syntaxTrees)
            {
                sourceBuilder.AppendLine($@"Console.WriteLine(@"" - {tree.FilePath}"");");
            }
            //   
            sourceBuilder.Append(@"
        }
    }
}");
            //      
            context.AddSource("helloWorldGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
        }

        public void Initialize(InitializationContext context)
        {
              //     
        }
    }
}

4. LangVersion .


<!--        -->
<PropertyGroup>
  <LangVersion>preview</LangVersion>
</PropertyGroup>

<!--   ItemGroup,       -->
<ItemGroup>
<!--   ,    "" ProjectReference. 
   'OutputItemType'  'ReferenceOutputAssmbly'. -->
    <ProjectReference Include="path-to-sourcegenerator-project.csproj" 
                      OutputItemType="Analyzer"
                      ReferenceOutputAssembly="false" />
</ItemGroup>

Roslyn, .


Visual Studio , . , :


public class SomeClassInMyCode
{
    public void SomeMethodIHave()
    {
        HelloWorldGenerated.HelloWorld.SayHello(); 
        //  Console.WriteLine("Hello World!")     
    }
}

: Visual Studio, IntelliSense


:


  • , , INotifyPropertyChanged,
  • , SourceGeneratorContext,
  • JSON- . .

Source Generators Cookbook.
GitHub.


, — , IntelliSense , Visual Studio.



. — . API . C# 9, API , .


C# : ! .NET , C# – . , - .


:



, .



Visual Studio , “ 1.0”. , . .NET 5 . , API, - OSS.


. , . .


FAQ


, . .


— , ?


— , , , . , . , , . , - , .


F#?


F#. . , F# , . — , C#, , C# .


?


. — . “”, . .


?


, . , , . C#, . -.


/ ?


. , / . , C#.


?


C# 9. , .


TFM ?


. .NET Standard 2.0 TFM . .NET Standard 2.0.


Visual Basic F#?


#. , . VB . F# — .


?


, . VB F# , , . . . , , .


Intellisense ? Visual Studio , ?


Visual Studio. . Visual Studio .


Visual Studio?


Visual Studio.


?


NuGet, , . .


Microsoft ?


. . , Microsoft .


LangVersion ?


Obwohl Quellcode-Generatoren technisch gesehen keine C # -Sprachenfunktion sind, befinden sie sich in der Vorschau. Anstatt nur für sie eine neue Einstellung einzuführen, haben wir beschlossen, dass es einfacher ist, den vorhandenen Schalter zu verwenden, mit dem Sie die Sprachfunktionen des C # -Compilers anzeigen können.


All Articles