一个用于创建C#装饰器/代理的工具






4.94/5 (26投票s)
描述了一个小型VS插件,用于从现有代码创建装饰器。
引言
本文讨论了C#编程语言中代理/装饰器的概念,并展示了一个Visual Studio插件,该插件有助于从您的代码创建此类对象。
要使用本文中提供的已编译插件,请将安装文件解压缩到您的Add-ins文件夹中。
问题
如果您曾经做过从C#进行文本代码生成,您可能知道子类化StringBuilder
并添加特定于您要构建的代码类型的功能是多么方便。您还会知道,您实际上不能子类化StringBuilder
,因为它被sealed
修饰了。一种选择是使用扩展方法,但是如果您想保留某个构建器类的缩进级别呢?您最终会创建HashTable
的WeakReference
类,所有这些都会变得很混乱。幸运的是,有一个(可以说是)更好的方法。
我说的是使用装饰器。StringBuilder
类的装饰器可以具有StringBuilder
具有的所有方法,以及更多方法。与static
扩展方法类不同,它可以保持特定于实例的状态。它还可以执行其他有趣且有用的操作,例如添加代理代码、更改返回类型以及其他有趣的事情。
传播(或代理)大量的属性赋值和方法调用并不有趣。这就是为什么我决定编写一个小工具来为我做这件事。让我们来看看这个工具的实际操作。
示例
好的,所以我想从CodeBuilder
类派生CSharpBuilder
、FSharpBuilder
、NemerleBuilder
等等,我该如何做呢?
步骤一(可选):我在Reflector中打开mscorlib,找到StringBuilder
类,并将其逐字复制到我的项目文件中(任何文件名都可以——它并不重要)。如果我正在为解决方案中的一个文件创建装饰器,我会跳过此步骤。由于StringBuilder
不在附近,我复制它。
不要费心修复丢失的引用或编译代码——没有必要。我们只是拖入了源代码,以便装饰器构建器可以找到它。
步骤二:现在,我右键单击我想要装饰器的项目,然后选择添加 | 装饰器
步骤三:现在,我在树中选择StringBuilder
类并勾选其框。我输入装饰器名称并按下确定按钮
由于许多StringBuilder
方法返回一个StringBuilder
对象,因此我收到一个警告,提示已检测到流畅接口
由于我想返回CodeBuilder
对象,因此我按“是”进行替换。
步骤四:这是最后一步。我已经有了我的类,所以我现在需要做的就是添加丢失的引用并进行一些清理,以便所有翻译错误的部分都被删除或使其可编译(Reflector并不完美,你知道的)。当然,我还删除了从Reflector复制的内容——它不再需要了。就是这样!我得到了我的装饰器。
public class CodeBuilder
{
private readonly StringBuilder stringBuilder;
private CodeBuilder(StringBuilder stringBuilder)
{
this.stringBuilder = stringBuilder;
}
public int Capacity
{
get
{
return stringBuilder.Capacity;
}
set
{
stringBuilder.Capacity = value;
}
}
// other members omitted
}
它是如何实现的?
该插件解析项目内容树并找到每个.cs文件。然后,它使用我在CodePlex上找到的一个免费的C#解析器来解析文件并从中构建可视化树。最后一部分非常明显——它只是遍历用户选择的类的结构,并创建传播方法/属性。
这个项目是我第一次(也是唯一一次)使用WF。装饰器是用一个非常简单的流程构建的。如果您感兴趣,这里就是它(不是太令人兴奋,是吗?)
未来与结论
您不必只在一个类上创建装饰器。如果您想要一些模拟的多重继承,您可以指定两个或多个类来装饰。提取接口和处理名称冲突将由您自己负责,因为我的插件不会直接处理这些。
此插件是我主要用于内部使用的名为P/factor的一组插件的一部分。我将在不久的将来撰写有关其他代码生成插件的文章。同时,您可以随意试用此插件。我也感谢评论和投票,因为这是我衡量我的文章是否有用的唯一指标。谢谢!