使用GetExecutingAssembly和GetTypes获取到带+<>c后缀的额外类型问题
问题原因与解决方案
你遇到的带+<>c后缀的类型,是C#编译器自动生成的闭包显示类(Display Class),属于编译器的实现细节,并不是你手动定义的类型。当你的代码中使用了lambda表达式、匿名方法,或者某些需要捕获外部变量的LINQ查询时,编译器会生成这类隐藏类来承载捕获的变量和匿名逻辑,它们会被嵌套在对应的宿主类中,所以在反射获取类型时会被一并返回。
你的临时过滤方法if (@class.ToString().Contains("<")) continue;虽然能暂时解决问题,但存在潜在风险:比如如果你的项目中有泛型类,它的ToString()结果会包含<(例如List<int>),这类合法类型会被误过滤掉,所以这个方案不够严谨。
更可靠的过滤方案
推荐通过检查类型是否带有CompilerGeneratedAttribute来识别编译器生成的类型,这是最准确的方式:
using System.Reflection; using System.Runtime.CompilerServices; // 获取程序集中所有非编译器生成的类型 var targetTypes = Assembly.GetExecutingAssembly().GetTypes() .Where(type => !type.IsDefined(typeof(CompilerGeneratedAttribute), inherit: false)) .ToList();
如果你只想排除这类闭包类(而保留其他可能的编译器生成类型,比如自动实现属性的幕后逻辑类),也可以通过判断类型名称的特征来过滤:
var targetTypes = Assembly.GetExecutingAssembly().GetTypes() .Where(type => !type.Name.Contains("+<>")) .ToList();
为什么会生成这个类?
你定义的WebJobLogsForErrorsCheck或它的基类MonitoringJob中,大概率存在lambda表达式、匿名方法,或者类似下面的代码逻辑:
// 示例:使用lambda会触发编译器生成闭包类 public void SomeMethod() { var someVar = "test"; var query = someCollection.Where(item => item == someVar); }
编译器为了捕获someVar变量,会自动生成带+<>c后缀的嵌套类,这就是你在反射结果中看到的额外类型。
内容的提问来源于stack exchange,提问作者Stefan Zvonar
相关产品推荐
相关产品推荐

