【C# | 分析器】禁止子类在覆写父类虚方法时调用父类方法实现

此分析器功能比较简陋,仅作个人备忘。

参考资料:https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/tutorials/how-to-write-csharp-analyzer-code-fix

将以下分析器代码编译为DLL后,将DLL添加到项目分析器列表中,即可进行相关分析。

分析器代码

using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;namespace DontCallBaseImplementation
{[AttributeUsage(AttributeTargets.Method, Inherited = false)]public class DontCallBaseImplementationAttribute : Attribute { }[DiagnosticAnalyzer(LanguageNames.CSharp)]public class DontCallBaseImplementationAnalyzer : DiagnosticAnalyzer{public const string DiagnosticId = "DontCallBaseImplementation";private static readonly LocalizableString Title = "Invalid base method implementation call";private static readonly LocalizableString MessageFormat = "Method '{0}' with [DontCallBaseImplementationAttribute] should not call base method implementation";private static readonly LocalizableString Description = "The method in the derived class calls the base method implementation which is marked with [DontCallBaseImplementationAttribute].";private const string Category = "Usage";private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category,DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description);public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }public override void Initialize(AnalysisContext context){context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);context.EnableConcurrentExecution();context.RegisterSyntaxNodeAction(AnalyzeSyntax, SyntaxKind.InvocationExpression);}private static void AnalyzeSyntax(SyntaxNodeAnalysisContext context){InvocationExpressionSyntax invocationExpression = (InvocationExpressionSyntax)context.Node;if (invocationExpression.Expression is MemberAccessExpressionSyntax memberAccess &&memberAccess.Expression is BaseExpressionSyntax){IMethodSymbol invokedSymbol = context.SemanticModel.GetSymbolInfo(invocationExpression).Symbol as IMethodSymbol;if (invokedSymbol == null) return;IMethodSymbol currentMethod = context.ContainingSymbol as IMethodSymbol;IMethodSymbol baseMethod = currentMethod?.OverriddenMethod;if (!SymbolEqualityComparer.Default.Equals(invokedSymbol, baseMethod)) return;AttributeData dontCallBaseImplAttr = baseMethod.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.Name == nameof(DontCallBaseImplementationAttribute));if (dontCallBaseImplAttr != null){Diagnostic diagnostic = Diagnostic.Create(Rule, invocationExpression.GetLocation(), memberAccess.Name);context.ReportDiagnostic(diagnostic);}}}}
}

添加分析器

在项目的配置文件(csproj)中,添加 ItemGroup 指定分析器引用:

< !--Add to YOUR_PROJECT.csproj-- >
< Project Sdk = "Microsoft.NET.Sdk" >< !--... -->< ItemGroup >< Analyzer Include = "ABSOLUTE_OR_RELATIVE_FOLDER\DontCallBaseImplementation.dll" /></ ItemGroup >< !--... --></ Project >

代码中的使用方法

定义一个 DontCallBaseImplementationAttribute 类(也可以直接使用分析器DLL中提供的同名类,但要为项目添加对DLL的依赖项):

[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class DontCallBaseImplementationAttribute : Attribute { }

在不希望子类覆写时调用父类方法实现的虚方法上,添加上述特性:

class BaseClass
{[DontCallBaseImplementation]public virtual void DoSomething(){Console.WriteLine("BaseClass.DoSomething()");}
}

之后,若子类重写方法时调用了父类方法实现,编辑器会报告错误:

class DerivedClass : BaseClass
{public override void DoSomething(){base.DoSomething(); // Will report an error}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/34874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于CRITIC-TOPSIS法的各地区评价

1.CRITIC-TOPSIS法原理 1.1 基本理论 CRITIC-TOPSIS法是一种结合CRITIC&#xff08;Criteria Importance Through Intercriteria Correlation&#xff09;法和TOPSIS&#xff08;Technique for Order Preference by Similarity to Ideal Solution&#xff09;法的综合评价方法…

深度学习语义分割算法之基础知识

文章目录 前言一、图像分割介绍1.语义分割2.实例分割3.全景分割 二、常见数据集格式1.PASCAL VOC2.MS COCO 三、语义分割结果四、语义分割常见评价指标1.Pixel Accuracy2.mean Accuracy3.mean IoU 五、语义分割标注工具结束语 &#x1f482; 个人主页:风间琉璃&#x1f91f; 版…

Python 入门 —— 描述器

Python 入门 —— 描述器 文章目录 Python 入门 —— 描述器描述器简单示例定制名称只读属性状态交互验证器类自定义验证器验证器的使用 对象关系映射 描述器 前面我们介绍了两种属性拦截的方式&#xff1a;特性&#xff08;property&#xff09;以及重载属性访问运算符&#…

更适合敏感口腔的护理牙刷

最近在用一款清九野小红盾舒敏牙刷&#xff0c;感觉它很适合牙龈敏感的人&#xff0c;让刷牙体验有了显著的提升。这款牙刷的柔软刷毛和精细设计让我的刷牙过程变得轻松愉快。它的内外圈双重植毛技术&#xff0c;在清洁牙齿的同时&#xff0c;还能深入牙缝&#xff0c;温和地去…

设计模式原则——单一职责原则(SPS)

设计模式原则 设计模式示例代码库地址&#xff1a; https://gitee.com/Jasonpupil/designPatterns 单一职责原则&#xff08;SPS&#xff09;&#xff1a; 又称单一功能原则&#xff0c;面向对象五个基本原则&#xff08;SOLID&#xff09;之一原则定义&#xff1a;一个类应…

linux启动jar包,提示jvm内存不足

出现场景 服务器内存还剩余很多&#xff0c;但是启动jar报内存不足 Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00007f66434f0000, 65536, 1) failed; error无法分配内存 (errno12) [thread 140076481570560 also had an error] # # Compiler re…

基于Docker的淘客返利平台部署

基于Docker的淘客返利平台部署 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在本文中&#xff0c;我们将探讨如何利用Docker技术来部署一个淘客返利平台。Doc…

还能这样执行命令?命令执行绕过及防护规则研究

一、引言 我是渗透工程师->很多小伙伴在做攻防实战时发现有时在命令执行的payload中穿插单双引号命令也能执行成功&#xff0c;有时却又不行。那么到底在什么条件下用什么样的方式能实现对命令的切分呢&#xff1f;其中的原理又是如何&#xff1f;有没有其他绕过方式&#…

openlayers 轨迹回放(历史轨迹),实时轨迹

本篇介绍一下使用openlayers轨迹回放&#xff08;历史轨迹&#xff09;&#xff0c;实时轨迹 1 需求 轨迹回放&#xff08;历史轨迹&#xff09;实时轨迹 2 分析 主要是利用定时器&#xff0c;不断添加feature 轨迹回放&#xff08;历史轨迹&#xff09;&#xff0c;一般是…

Ubuntu 22.04 MySQL安装并设置远程访问

Ubuntu 22.04 LTS环境下 1 安装 # 更新软件包列表 sudo apt update# 查看可使用的安装包 sudo apt search mysql-server# 安装最新版本&#xff08;显示冲突装不了&#xff0c;可以先卸了再装&#xff09; sudo apt install -y mysql-server # 安装指定版本 sudo apt install…

rga_mm: RGA_MMU unsupported Memory larger than 4G!解决

目录 报错完整log如下:解决方案:报错完整log如下: [ 3668.824164] rga_mm: RGA_MMU unsupported Memory larger than 4G! [ 3668.824305] rga_mm: scheduler core[4] unsupported mm_flag[0x0]! [ 3668.824320] rga_mm: rga_mm_map_buffer map dma_buf err

如何有效地优化 Erlang 程序的内存使用,以应对大规模数据处理的需求?

要有效地优化Erlang程序的内存使用&#xff0c;以应对大规模数据处理的需求&#xff0c;可以考虑以下几个方面&#xff1a; 减少不必要的内存分配&#xff1a;避免过多的数据复制和不必要的数据结构创建。可以使用Erlang的二进制数据类型来避免数据复制&#xff0c;使用原子数据…

Linux环境下安装MySQL5.7.20(源码安装)

&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;本专栏主要发表mysql实战的文章&#xff0c;文章主要包括&#xff1a; 各版本数据库的安装、备份和恢复,性能优化等内容的学习。。 &#x1f4e3; ***如果需要观看配套视频的小伙伴们&#xff0c;请…

【Apache Doris】周FAQ集锦:第 8 期

【Apache Doris】周FAQ集锦&#xff1a;第 8 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和…

MySQL集群如何实现读写分离

数据源配置&#xff1a;定义了主从数据库的连接池。读写分离规则&#xff1a;通过MasterSlaveRuleConfiguration定义了主从数据库的读写分离规则。负载均衡算法&#xff1a;定义了从数据库的负载均衡算法。创建ShardingDataSource&#xff1a;使用数据源和读写分离规则创建了Sh…

STM32学习-HAL库 定时器

这里先介绍一些HAL的一些库函数&#xff0c;HAL_XXX_Init()这种是外设初始化函数&#xff0c;一般是传入结构体。 HAL_XXX_MspInit()这种是外设硬件相关的初始化函数&#xff0c;包括GPIO,NVIC,CLOCK等&#xff0c;一般会在HAL_XXX_Init()中调用。HAL_XXX_IT()这是与外设中断相…

Scikit-learn:原理与使用指南

文章目录 1. Scikit-learn 的原理1.1 一致性API1.2 模块化和可扩展性1.3 高效性 2. Scikit-learn 的使用2.1 安装 Scikit-learn2.2 导入必要的库和数据2.3 训练模型2.4 预测和评估2.5 交叉验证和网格搜索 3. 总结 Scikit-learn 是 Python 中一个非常强大且易于使用的机器学习库…

【CSS】深入探讨 CSS 的 `calc()` 函数

深入探讨 CSS 的 calc() 函数 calc() 是一个 CSS 函数&#xff0c;用于在样式表中进行数学计算&#xff0c;从而动态地设置 CSS 属性值。它允许开发者在指定长度、百分比、数值等时&#xff0c;进行加减乘除运算。通过 calc() 函数&#xff0c;我们可以实现更灵活和响应式的设…

vue3项目使用@antv/g6实现可视化流程功能

文章目录 项目需求一、需要解决的问题二、初步使用1.动态数据-组件封装(解决拖拽会留下痕迹的问题&#xff0c;引用图片&#xff0c;在节点右上角渲染图标&#xff0c;实现&#xff0c;事现旋转动画&#xff0c;达到loading效果)2.文本太长&#xff0c;超出部分显示(...),如下函…

Fluent udf编译的一些注意事项

Fluent udf编译的一些注意事项 参考链接&#xff1a;1.fluent UDF编译环境处理_哔哩哔哩_bilibili 2.【觉兽课堂】ANSYS FLUENT UDF教学02&#xff1a;UDF语法及编写 小白入门必备_哔哩哔哩_bilibili #1 需要注意的内容 ##1.1 修改vs的路径 在fluent路径中&#xff0c;打开ud…