这方面的典型例子是数据访问,但我还有另一个例子。我曾在一个通过串行端口、套接字等进行通信的消息传递系统上工作,但我发现我不得不一遍又一遍地编写这样的类:
public class FooMessage
{
public FooMessage()
{
}
public FooMessage(int bar, string baz, DateTime blah)
{
this.Bar = bar;
this.Baz = baz;
this.Blah = blah;
}
public void Read(BinaryReader reader)
{
this.Bar = reader.ReadInt32();
this.Baz = Encoding.ASCII.GetString(reader.ReadBytes(30));
this.Blah = new DateTime(reader.ReadInt16(), reader.ReadByte(),
reader.ReadByte());
}
public void Write(BinaryWriter writer)
{
writer.Write(this.Bar);
writer.Write(Encoding.ASCII.GetBytes(
this.Baz.PadRight(30).Substring(0, 30)));
writer.Write((Int16)this.Blah.Year);
writer.Write((byte)this.Blah.Month);
writer.Write((byte)this.Blah.Day);
}
public int Bar { get; set; }
public string Baz { get; set; }
public DateTime Blah { get; set; }
}
如果你愿意的话,试着想象一下,为不少于 300 种不同类型的消息编写这段代码。一遍又一遍地编写同样无聊、乏味、容易出错的代码。在我决定只写一个代码生成器对我来说更容易之前,我设法写了其中的 3 个,所以我这样做了。
我不会发布代码生成代码,这是很多神秘的 CodeDom 东西,但最重要的是我能够将整个系统压缩成一个 XML 文件:
<Messages>
<Message ID="12345" Name="Foo">
<ByteField Name="Bar"/>
<TextField Name="Baz" Length="30"/>
<DateTimeField Name="Blah" Precision="Day"/>
</Message>
(More messages)
</Messages>
这容易多少? (反问。)我终于可以呼吸了。我什至添加了一些花里胡哨的东西,所以它能够生成一个“代理”,我可以编写这样的代码:
var p = new MyMessagingProtocol(...);
SetFooResult result = p.SetFoo(3, "Hello", DateTime.Today);
最后我想说,这节省了我编写 7500 行代码的时间,并将 3 周的任务变成了 3 天的任务(好吧,加上编写代码生成所需的几天)。
结论:代码生成只适用于相对少数的问题,但当你能够使用一个时,它会让你保持理智。