生成代码从T到T1、T2、Tn自动生成多个类型的泛型(2)

这个类中加入了非常多种常见的泛型字符串特征,当然是采用最笨的字符串替换方法。如果感兴趣优化优化,可以用正则表达式,或者使用 Roslyn 扩展直接拿语法树。

于是,在 Program.cs 中调用以上代码即可完成泛型生成。我写了一个简单的版本,可以将每一个命令行参数解析为一个需要进行转换的泛型类文件。

using System.IO; using System.Linq; using System.Text; using Walterlv.BuildTools; class Program { static void Main(string[] args) { foreach (var argument in args) { GenerateGenericTypes(argument, 4); } } private static void GenerateGenericTypes(string file, int count) { // 读取原始文件并创建泛型代码生成器。 var template = File.ReadAllText(file, Encoding.UTF8); var generator = new GenericTypeGenerator(template); // 根据泛型个数生成目标文件路径和文件内容。 var format = GetIndexedFileNameFormat(file); (string targetFileName, string targetFileContent)[] contents = Enumerable.Range(2, count - 1).Select(i => (string.Format(format, i), generator.Generate(i)) ).ToArray(); // 写入目标文件。 foreach (var writer in contents) { File.WriteAllText(writer.targetFileName, writer.targetFileContent); } } private static string GetIndexedFileNameFormat(string fileName) { var directory = Path.GetDirectoryName(fileName); var name = Path.GetFileNameWithoutExtension(fileName); if (name.EndsWith("1")) { name = name.Substring(0, name.Length - 1); } return Path.Combine(directory, name + "{0}.cs"); } }

考虑到这是 Demo 级别的代码,我将生成的泛型个数直接写到了代码当中。这段代码的意思是按文件名递增生成多个泛型类。

例如,有一个泛型类文件 Demo.cs,则会在同目录生成 Demo2.cs,Demo3.cs,Demo4.cs。当然,Demo.cs 命名为 Demo1.cs 结果也是一样的。

在要生成代码的项目中添加“预先生成事件命令行”:

"$(ProjectDir)..\CodeGenerator\$(OutDir)net47\CodeGenerator.exe" "$(ProjectDir)..\Walterlv.Demo\Generic\IDemoFile.cs" "$(ProjectDir)..\..\Walterlv.Demo\Generic\DemoFile.cs"

现在,编译此项目,即可生成多个泛型类了。

彩蛋

如果你仔细阅读了 GenericTypeGenerator 类的代码,你将注意到我为生成的文件加上了条件编译符“GENERATED_CODE”。这样,你便可以使用 #ifdef GENERATED_CODE 来处理部分不需要进行转换或转换有差异的代码了。

这时写代码,是不是完全感受不到正在写模板呢?既有代码着色,又适用于团队其他开发者的开发环境。是的,个人认为如果带来便捷的同时注意不到工具的存在,那么这个工具便是好的。

如果将传参改为自动寻找代码文件,将此工具发布到 NuGet,那么可以通过 NuGet 安装脚本将以上过程全自动化完成。

参考资料

总结

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdsfzs.html