C #: Apresentando geradores de código-fonte

imagem


Temos o prazer de apresentar uma prévia dos geradores de código-fonte. Esse é um novo recurso que permite aos desenvolvedores de C # analisar o código personalizado e criar novos arquivos C #, que por sua vez podem ser adicionados ao processo de compilação. Isso acontece com a ajuda de um novo componente - o Source Generator.


Para começar com os geradores, você precisará das mais recentes visualizações do .NET 5 e do Visual Studio . Nota: O Visual Studio é necessário para criar o gerador de código-fonte. Isso será alterado na próxima visualização do .NET 5.


O que é um gerador de código-fonte?


Um gerador de código-fonte é um pedaço de código que é executado durante a compilação, verifica o programa e cria arquivos adicionais, que são compilados com o restante do código.


Aqui estão dois recursos principais que permitem implementar:


  • Obtenha um objeto de compilação que represente todo o código de usuário compilado. Esse objeto pode ser analisado e você pode escrever um código que funcione com modelos sintáticos e semânticos de código compilado, como é o caso dos analisadores modernos.
  • C# , . , .

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


:


imagem


.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 ?


Embora os geradores de código-fonte não sejam tecnicamente um recurso de linguagem C #, eles estão na visualização. Em vez de introduzir uma nova configuração apenas para eles, decidimos que seria mais fácil usar a opção existente, o que permite exibir os recursos de idioma do compilador C #.


All Articles