最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

环球热头条丨Source Generator-扩充原有代码

来源:博客园

我们经常会遇到,原有代码中新增方法,扩展我们自己写的代码。这个使用Source Generator也可以实现


【资料图】

  1. 在上一章的接触上新增类库(AugmentingGeneratorMethod)

  2. 添加Microsoft.CodeAnalysis.Analyzers 和 Microsoft.CodeAnalysis.CSharp引用:

                  all      runtime; build; native; contentfiles; analyzers; buildtransitive      
  3. 在SourceGeneratorConsole项目中添加一个类AugmentClass,添加如下代码:

    namespace SourceGeneratorConsole{    public partial class AugmentClass    {        public void AugmentMethod()        {            // 调用代码生成器中的方法            this.GeneratedMethod();        }    }}

    调用的GeneratedMethod方法为需要代码生成器增加的,其中代码生成器需要获得命名空间和该class类才能让this生效。

  4. 在AugmentingGeneratorMethod中新建一个cs文件,命名为AugmentingGenerator。添加如下代码

    using Microsoft.CodeAnalysis;using Microsoft.CodeAnalysis.CSharp.Syntax;using Microsoft.CodeAnalysis.Text;using System;using System.Diagnostics;using System.Text;namespace AugmentingGeneratorMethod{    [Generator]    public class AugmentingGenerator : ISourceGenerator    {        public void Initialize(GeneratorInitializationContext context)        {            // 自定义一个语法接收器的工厂,然后通过该工厂向已有的class类中添加新方法            context.RegisterForSyntaxNotifications(() => new AugmentSyntaxReceiver());        }        public void Execute(GeneratorExecutionContext context)        {            // 获得创建的语法接收器,然后通过context进行操作            AugmentSyntaxReceiver syntaxReceiver = (AugmentSyntaxReceiver)context.SyntaxReceiver;            // 通过语法接收器获得class类            ClassDeclarationSyntax augmentClass = syntaxReceiver.ClassToAugment;            //判断是否有这个类            if (augmentClass is null)            {                //没有找到就不做任何事情                return;            }            //找到了就添加一个方法            SourceText sourceText = SourceText.From($@"                namespace {syntaxReceiver.SpaceToAugment.Name.GetText()}                {{                    public partial class {augmentClass.Identifier}                    {{                        private void GeneratedMethod()                        {{                            Console.WriteLine(""Hello, augmentClass!"");                        }}                    }}                }}", Encoding.UTF8);            context.AddSource("augmentClass.Generated.cs", sourceText);        }    }}
  5. 在AugmentingGeneratorMethod项目中添加语法接收器(AugmentSyntaxReceiver),代码如下

    using Microsoft.CodeAnalysis.CSharp.Syntax;using Microsoft.CodeAnalysis;namespace AugmentingGeneratorMethod{    class AugmentSyntaxReceiver : ISyntaxReceiver    {        // 获得类名        public ClassDeclarationSyntax ClassToAugment { get; private set; }        // 获得命名空间        public NamespaceDeclarationSyntax SpaceToAugment { get; private set; }        public void OnVisitSyntaxNode(SyntaxNode syntaxNode)        {            //Debugger.Launch();            if (syntaxNode is NamespaceDeclarationSyntax csd) {                SpaceToAugment = csd;            }            // 判断是否有AugmentClass,如果有则赋值            if (syntaxNode is ClassDeclarationSyntax cds &&                cds.Identifier.ValueText == "AugmentClass")            {                                ClassToAugment = cds;            }        }    }}
  6. 如果想进行调试,可以使用Debugger.Launch()。

  7. 在SourceGeneratorConsole的Program中添加调用

    //在原有的代码中进行扩展AugmentClass augment = new AugmentClass();augment.AugmentMethod();
  8. 别忘记,需要引用AugmentingGeneratorMethod项目,并添加两个属性

          
  9. 编译运行后,结果正常显示

  10. 总结

    当生成出现错误时,大概率是未添加Generator项目的引用或者未添加OutputItemType和ReferenceOutputAssembly属性

关键词: