C#9.0源生成器如何过滤带[CompilerGenerated]特性的编译器生成类
解决方案
你只需要在原有类型筛选逻辑中增加编译器生成类型的过滤规则即可,修改后的筛选代码如下:
var neededTypes = types.Where(t => { // 过滤带有[CompilerGenerated]特性的编译器生成类 if (t.GetAttributes().Any(attr => attr.AttributeClass?.Name == nameof(System.Runtime.CompilerServices.CompilerGeneratedAttribute))) return false; // 可选过滤:只保留公开类,因为需要注册到DI容器的类通常都是公开可访问的 if (t.DeclaredAccessibility != Accessibility.Public) return false; // 可选双重保险:过滤名称包含尖括号的类型,编译器生成的类型名称都会携带特殊符号< > if (t.Name.Contains('<')) return false; string @namespace = t.ContainingNamespace.ToString(); if (@namespace.Contains("Test") && !t.Interfaces.IsEmpty && t.TypeKind == TypeKind.Class) { namespaces.Add(t.ContainingNamespace.ToString()); namespaces.Add(t.Interfaces[0].ContainingNamespace.ToString()); return true; } return false; }).ToList();
原理说明
编译错误的成因是C#编译器会为async方法生成私有嵌套的状态机类,这类类默认会被标记[CompilerGenerated]特性,且类名包含尖括号等特殊字符。原有逻辑没有过滤这类类型,导致生成注册代码时直接输出了无效的类名字符串,触发语法错误。
添加上述过滤规则后,所有编译器自动生成的类型都会被排除,只会保留自定义的业务类参与DI注册,即可解决所有编译报错。
内容的提问来源于stack exchange,提问作者IgalKF
相关产品推荐
相关产品推荐

