在T4模板中能否检测类的继承属性并自定义字段生成?
当然可以在T4模板里检测类的继承属性,轻松区分父类和子类自己的字段!我给你两种实用的实现方式,你可以根据自己的场景选择:
方法一:使用反射(通用场景)
这种方式适用于已经编译好的程序集,或者你能在T4模板中引用到目标类型的场景。核心思路是通过反射获取属性的DeclaringType——如果这个类型等于当前类的类型,就是子类自身的属性;反之就是继承来的。
首先在T4模板头部引入必要的程序集和命名空间:
<#@ assembly name="System.Core" #> <#@ assembly name="YourProjectAssembly.dll" #> <!-- 替换成包含User和ManagedRecord的程序集路径或名称 --> <#@ import namespace="System" #> <#@ import namespace="System.Reflection" #> <#@ import namespace="System.Linq" #>
然后编写核心逻辑,区分并处理两类属性:
<# // 获取目标类型 Type userType = typeof(User); // 获取所有公共实例属性(包括继承的) var allProperties = userType.GetProperties(BindingFlags.Public | BindingFlags.Instance); // 拆分出子类自身的属性和继承的属性 var ownProperties = allProperties.Where(p => p.DeclaringType == userType); var inheritedProperties = allProperties.Where(p => p.DeclaringType != userType); #> <!-- 先输出子类自身的字段,自定义格式 --> ## 子类自身字段 <# foreach(var prop in ownProperties) { #> public <#= prop.PropertyType.Name #> <#= prop.Name #> { get; set; } <# } #> <!-- 再输出继承的字段,做特殊标记处理 --> ## 继承自父类的字段 <# foreach(var prop in inheritedProperties) { #> // 来自<#= prop.DeclaringType.Name #>的继承字段 public <#= prop.PropertyType.Name #> <#= prop.Name #> { get; set; } <# } #>
方法二:使用EnvDTE(VS项目内模板场景)
如果你的T4模板是直接在Visual Studio项目中使用,想要基于项目里的源码类而不是编译后的程序集处理,可以借助EnvDTE来获取类型信息,判断属性是否是外部(继承)的。
先引入EnvDTE相关的程序集和命名空间:
<#@ assembly name="EnvDTE" #> <#@ import namespace="EnvDTE" #> <#@ import namespace="System.Linq" #>
然后编写逻辑:
<# // 获取VS的DTE服务 DTE dte = (DTE)Host.ResolveService(typeof(DTE)); // 找到项目中的User.cs文件对应的代码模型 CodeType userClass = dte.Solution .FindProjectItem("User.cs") // 替换成你的User类文件路径 .FileCodeModel .CodeElements .OfType<CodeType>() .First(); // 遍历所有成员,区分继承和自身属性 foreach(CodeElement elem in userClass.Members) { if(elem is CodeProperty prop) { // 判断是否为继承属性:Location为External表示来自父类 if(prop.Info.Location == vsCMInfoLocation.vsCMInfoLocationExternal) { WriteLine($"// 继承字段:{prop.Name}(来自{prop.Info.Parent.Name})"); } else { WriteLine($"自身字段:{prop.Name}"); } } } #>
这样你就可以完全掌控两类字段的输出逻辑了——不管是调整顺序、添加注释,还是过滤某些继承字段,都能轻松实现。
内容的提问来源于stack exchange,提问作者AnotherDeveloper
相关产品推荐
相关产品推荐

