如何以编程方式将属性插入到.cs源文件中的类中
本文关键字:cs 源文件 插入 属性 编程 方式 | 更新日期: 2023-09-27 18:04:18
我正在创建一个用于向现有类的源代码插入属性的自动化工具。例如:我有一个像这样的现有源代码:
public class MyClass
{
//class members goes here
}
我想把它修改成这样
public class MyClass
{
//class members goes here
public string MyProp { get; set; }
}
并保存到同一个文件。
类名、属性类型和属性名是预先知道的,可以作为操作的参数。有什么简单的方法吗?也许regex替换将为此工作,但我不知道使用哪个表达式将是灵活的,无论源代码的新行,空白和标识策略。
EDIT:我正在寻找的只是自动生成源代码,而不是在运行时操作类
一种干净的方法是使用T4模板生成部分类。
T4模板是在编译时生成代码的好方法。
这些生成的文件不应该被开发人员修改,相反,开发人员创建另一个文件,其中包含部分类成员的附加定义。
这样,您就可以一次又一次地调整和运行生成器,而不会扰乱自定义代码。
下面使用正则表达式的方法应该可以工作,尽管我不认为这可能是做您需要的事情的最佳方法。不太清楚,那要看你的需求了。我一直这样做(创建修改.cs
文件的脚本,或从 notepad++ 创建宏)。也许您还想看看部分类。
string text =
@"namespace X {
public class MyClass {
//Text here
}
}";
string className = "MyClass";
string propertyType = "string";
string propertyName = "MyProperty";
string regex = string.Format(@"( *)((public?)'s*(static)?'s*class's+{0}'s*{{)", className);
string replacement = string.Format("$1$2'r'n'r'n$1 public {0} {1} {{ get; set; }}", propertyType, propertyName);
var modified = Regex.Replace(text, regex, replacement);
Console.WriteLine(modified);
上面的代码将打印:
namespace X {
public class MyClass {
public string MyProperty { get; set; }
//Text here
}
}
Edit:可以看到,它正确地缩进了代码。它使用包含类定义的行中相同数量的空格+ 4。如果你想添加一个选项卡,或者其他什么,你可以改变正则表达式
用于在运行时添加
程序集不能在运行时更改,所以您需要在运行时生成一个DLL并加载它,或者您可以使用这个问题中所描述的ExpandoObject
用于在编译时添加
如果您不想在运行时添加代码,那么您需要查找CodeDom
添加运行时间和编译时间
只是想加入另一个选项。虽然在很多方面你都不想这么做,但至少从你提供的那一点信息来看。
你可以使用IL编织。这个选项发生在编译之后(到MSIL),但是在运行之前。其结果是,您的类获得了编译时操作的所有好处,但提供了比CodeDom所能提供的更多信息。
MSIL编织的实现包括PostSharp。Net(商业产品)和Mono。Cecil(注意:不要让Mono部分欺骗了你,它也可以在。net上工作)。
的优势包括:
- 它(运行时)和编译时方法一样快
- 你有很多CodeDom丢失的信息(部分类是CodeDom中一个特别痛苦的问题)
缺点包括:
- 编织是困难的(你甚至失去了编译时的检查) IDE对编织的支持非常少
您可以尝试用Ruby编写的通用代码生成器cog。Cog有一个嵌入特性,这将非常适合您的目的。要实现您的目标,您可以这样修改您的类
public class MyClass
{
// class members goes here
// cog: auto-properties
}
然后写一个齿轮生成器(一个简短的ruby脚本),像这样
embed 'auto-properties' do |c|
" /* whatever you return gets injected into #{c.filename} */"
end
在本例中,c
是EmbedContext的一个实例。设置好生成器后,使用命令行调用
$ cog gen
Updated src/MyClass.cs - 1st occurrence of embed 'auto-properties'
现在你的类看起来像这样
public class MyClass
{
// class members goes here
// cog: auto-properties {
/* whatever you return gets injected into MyClass.cs */
// cog: }
}
如何生成给定文件名的属性取决于您。cog非常灵活,还支持使用ERB模板生成代码。