【Unity】 使用代码分析(Roslyn Analyzers)实现自动代码审查(Code Review)

本文介绍了如何使用RoslynAnalyzers在Unity开发环境中实现自动代码审查,包括公共和私有权限字段命名规则、代码优化建议、避免直接继承MonoBehaviour等,并展示了如何编写一个基础的类名长度检查分析器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Roslyn Analyzers

Roslyn Analyzers是.NET编译平台的代码分析程序,用以检查 C# 或 Visual Basic 代码的样式、质量、可维护性、设计及其他问题。

Code Review

虽然人工Code Review能检查出100%(取决于Reviewer的水平)的代码问题,但很多简单明了的设计或性能上的优化改进意见,我们依然想要它在程序员编码时便实时提醒出来,所以我们需要自动Code Review

自动 Code Review 案例

例如,目前我们的自动Code Review系统包含但不仅限于如下这些案例:

1.public、internal权限的字段建议以大写字母开头。

ID:D0001
类型:Design(设计改进意见)
级别:警告(不影响程序执行)
在这里插入图片描述

2.private、protected权限的字段建议以下划线+小写字母开头。

ID:D0002
类型:Design(设计改进意见)
级别:警告(不影响程序执行)
在这里插入图片描述

3.不建议直接继承 MonoBehaviour,建议继承至 HTBehaviour。

ID:D0007
类型:Design(设计改进意见)
级别:警告(不影响程序执行)
在这里插入图片描述

4.不建议使用 Input 判断输入或获取鼠标位置,建议使用 Main.m_Input 替代。

ID:O0001
类型:Optimize(代码优化意见)
级别:警告(不影响程序执行)
在这里插入图片描述

5.不建议在 Update、FixedUpdate、OnUpdateFrame 等帧执行方法中调用 GetComponent 方法,建议将组件缓存。

ID:O0002
类型:Optimize(代码优化意见)
级别:警告(不影响程序执行)
在这里插入图片描述

6.多个字符串串联(3个或以上)建议使用【$语法】或【string.Format】或【StringBuilder】替代。

ID:O0003
类型:Optimize(代码优化意见)
级别:警告(不影响程序执行)
在这里插入图片描述

7.float类型不建议使用 == 判断相等,建议使用 Mathf.Approximately 判断约等。

ID:O0004
类型:Optimize(代码优化意见)
级别:警告(不影响程序执行)
在这里插入图片描述

8.类必须添加XML文档注释。

ID:F0001
类型:Force(强制规范)
级别:错误(编译级错误,影响程序执行)
在这里插入图片描述

9.public、internal权限的方法必须添加XML文档注释。

ID:F0002
类型:Force(强制规范)
级别:错误(编译级错误,影响程序执行)
在这里插入图片描述

反馈至Unity编辑器

自动Code Review会以其对应的级别(警告还是错误)同步反馈至Unity编辑器的Console窗口,如果是错误级别,则编辑器将无法播放,必须解决掉该优化改进意见。
在这里插入图片描述

实现步骤

开发环境

  • Visual Studio 2022(社区版)
  • Unity 2022.3.17

一、新建VS工程

新建一个VS工程,模板为类库(且为面向.NET Standard,以兼容Unity),工程名称为CodeReview
在这里插入图片描述

二、管理NuGet程序包

鼠标右击解决方案,选择管理NuGet程序包
在这里插入图片描述

三、安装Microsoft.CodeAnalysis.CSharp包

搜索并安装Microsoft.CodeAnalysis.CSharp包,3.8.0版本(Unity官方文档要求为该版本)
在这里插入图片描述

四、编写分析器程序

1.新建类DiagnosticAnalyzer01

新建类DiagnosticAnalyzer01,继承至DiagnosticAnalyzer

namespace CodeReview
{
    public class DiagnosticAnalyzer01 : DiagnosticAnalyzer
    {
        
    }
}

2.实现抽象方法

实现该类的抽象方法:(该类将用于实现一个检测类名不能过短的分析器)

namespace CodeReview
{
    /// <summary>
    /// T001:类名定义不能过短。
    /// </summary>
    [DiagnosticAnalyzer(LanguageNames.CSharp)]
    public class DiagnosticAnalyzer01 : DiagnosticAnalyzer
    {
        public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => throw new NotImplementedException();

        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
            //注册类定义语法回调
            context.RegisterSyntaxNodeAction(OnSyntaxNodeAction, SyntaxKind.ClassDeclaration);
        }

		//当任意类定义语法编译时,将回调此方法
        private void OnSyntaxNodeAction(SyntaxNodeAnalysisContext context)
        {
           
        }
    }
}

3.编写分析器代码

接下来就是在回调方法中编写分析器代码:

namespace CodeReview
{
    /// <summary>
    /// T001:类名定义不能过短。
    /// </summary>
    [DiagnosticAnalyzer(LanguageNames.CSharp)]
    public class DiagnosticAnalyzer01 : DiagnosticAnalyzer
    {
        public DiagnosticDescriptor Rule
        {
            get
            {
                if (_descriptor == null)
                {
                    _descriptor = new DiagnosticDescriptor(
                    "T001",
                    "类名定义不能过短。",
                    "类名定义不能过短。",
                    "Test",
                    DiagnosticSeverity.Error,
                    true);
                }
                return _descriptor;
            }
        }
        public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);

        private DiagnosticDescriptor _descriptor;

        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
            context.RegisterSyntaxNodeAction(OnSyntaxNodeAction, SyntaxKind.ClassDeclaration);
        }

        private void OnSyntaxNodeAction(SyntaxNodeAnalysisContext context)
        {
            ClassDeclarationSyntax classDeclaration = (ClassDeclarationSyntax)context.Node;
            //发现类名过短
            if (classDeclaration.Identifier.ToString().Length <= 3)
            {
                //上报分析器
                context.ReportDiagnostic(Diagnostic.Create(Rule, classDeclaration.Identifier.GetLocation()));
            }
        }
    }
}

4.生成解决方案

鼠标右击解决方案,选择生成
在这里插入图片描述
此时,我们的分析器:T001:类名定义不能过短就编写完成了。

五、使用分析器程序

1.浏览dll

鼠标右击解决方案,选择在文件资源管理器中打开文件夹
在这里插入图片描述

2.拷贝dll

进入bin/Debug/netstandard2.0目录,将CodeReview.dll拖拽到任意Unity编辑器中的任意Editor目录下:
在这里插入图片描述

3.设置dll

选中CodeReview.dll,设置为下图的导入设置:
在这里插入图片描述

4.新建一个脚本

此时就可以新建一个脚本进行测试了,我们新建脚本T1,如果不出意外,你将收获一个错误提示:
在这里插入图片描述

六、总结

如上,一个测试分析器程序便开发完成了,如果你能熟悉语法分析,我想你应该知道,在分析器程序中,你将无所不能。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神码编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值