65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (26投票s)

2008 年 12 月 7 日

CPOL

4分钟阅读

viewsIcon

63401

downloadIcon

524

描述了一个小型VS插件,用于从现有代码创建装饰器。

引言

本文讨论了C#编程语言中代理/装饰器的概念,并展示了一个Visual Studio插件,该插件有助于从您的代码创建此类对象。

要使用本文中提供的已编译插件,请将安装文件解压缩到您的Add-ins文件夹中。

问题

如果您曾经做过从C#进行文本代码生成,您可能知道子类化StringBuilder并添加特定于您要构建的代码类型的功能是多么方便。您还会知道,您实际上不能子类化StringBuilder,因为它被sealed修饰了。一种选择是使用扩展方法,但是如果您想保留某个构建器类的缩进级别呢?您最终会创建HashTableWeakReference类,所有这些都会变得很混乱。幸运的是,有一个(可以说是)更好的方法。

我说的是使用装饰器。StringBuilder类的装饰器可以具有StringBuilder具有的所有方法,以及更多方法。与static扩展方法类不同,它可以保持特定于实例的状态。它还可以执行其他有趣且有用的操作,例如添加代理代码、更改返回类型以及其他有趣的事情。

传播(或代理)大量的属性赋值和方法调用并不有趣。这就是为什么我决定编写一个小工具来为我做这件事。让我们来看看这个工具的实际操作。

示例

好的,所以我想从CodeBuilder类派生CSharpBuilderFSharpBuilderNemerleBuilder等等,我该如何做呢?

步骤一(可选):我在Reflector中打开mscorlib,找到StringBuilder类,并将其逐字复制到我的项目文件中(任何文件名都可以——它并不重要)。如果我正在为解决方案中的一个文件创建装饰器,我会跳过此步骤。由于StringBuilder不在附近,我复制它。

不要费心修复丢失的引用或编译代码——没有必要。我们只是拖入了源代码,以便装饰器构建器可以找到它。

步骤二:现在,我右键单击我想要装饰器的项目,然后选择添加 | 装饰器

1.jpg

步骤三:现在,我在树中选择StringBuilder类并勾选其框。我输入装饰器名称并按下确定按钮

2.jpg

由于许多StringBuilder方法返回一个StringBuilder对象,因此我收到一个警告,提示已检测到流畅接口

3.jpg

由于我想返回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。装饰器是用一个非常简单的流程构建的。如果您感兴趣,这里就是它(不是太令人兴奋,是吗?)

4.jpg

未来与结论

您不必只在一个类上创建装饰器。如果您想要一些模拟的多重继承,您可以指定两个或多个类来装饰。提取接口和处理名称冲突将由您自己负责,因为我的插件不会直接处理这些。

此插件是我主要用于内部使用的名为P/factor的一组插件的一部分。我将在不久的将来撰写有关其他代码生成插件的文章。同时,您可以随意试用此插件。我也感谢评论和投票,因为这是我衡量我的文章是否有用的唯一指标。谢谢!

© . All rights reserved.