许多魔术数字

Bon*_*ngo 3 c# linq magic-numbers

我有一个项目,我将消息从一种格式转换为另一种格式.消息由id标识.我有一个带有一种格式的id的MappingTable和另一种格式的相应id.

例如:2000 = 153

id是整数

我通过以下方式添加所有这些内容:

this.AddMappingEntry(2400, 2005, true, false);
Run Code Online (Sandbox Code Playgroud)

此方法将映射条目添加到映射列表中.我可以通过linq过滤列表,这样我就可以在收到值为2400的消息时找到正确的映射.

自项目启动以来,它已经发展了很多,这导致了许多重构和许多具有特殊行为的id.我必须控制消息是否是特殊类型.

if(message.id == 153)
{
    //special behavior
}
Run Code Online (Sandbox Code Playgroud)

我该怎样处理这个最优雅的?我应该使用许多描述消息类型的常量还是有另一种更优雅的方式?

编辑:

我改回了这个问题.我有头记录和子记录.但是整个守则都使用了这些记录的Id.由于有大约200个不同的Id,我想知道我应该用这些神奇的数字做什么.我写的工具是转换器.

结构如下

     +------+         +-------------+      +---------+
     | DAL  +-------> |  CONVERTER  +----> | WRITER  |
     +------+         +-------------+      +---------+
Run Code Online (Sandbox Code Playgroud)

Converter类看起来大致如此

    +------------+
    |BaseClass   |
    +-----+------+
          ^
          |
    +-----+------+
    |BaseRecord  +^-------------+----------------------+
    +------+-----+              |                      |
           ^                    |                      |
           |                    |                      |
    +------+-----+      +-------+--------+     +-------+--------+
    | HeadRecord |      |   RecordType1  |     |   RecordType2  |
    +------------+      +----------------+     +----------------+
Run Code Online (Sandbox Code Playgroud)

BaseRecord扩展了Baseclass,所有其他类扩展了BaseRecord.总共我有5个Record类型,其中recordId为1-5.在这条记录中有几个subrecordId(~50),它们仅用于在写入过程之后分别识别写入者后面的记录.

问题是有些记录从不同的字段中读取了一些值,而另一些记录则导致我需要识别记录的一些特殊情况.

这导致了问题: 如果我在我的班级和转换器中使用它们,我有许多神奇的数字,没人知道它们是什么.我如何避免这些神奇的数字?我很开心,如果我使用那些,我的课程中会有50多个const值.有没有办法避免魔术数字和一大堆const值?对此有什么正确的重构?

das*_*ght 5

如果您可以将特殊行为概括为一组操作,那么您应该能够这样做:

private static readonly IDictionary<int,Action> messageBehavior =
    new Dictionary<int,Action> {
        {153, () => { Console.WriteLine("Special action"); } },
        {154, () => { Console.WriteLine("Another special action"); } }
    };
Run Code Online (Sandbox Code Playgroud)

现在,您可以通过消息ID从字典中获取操作,并在可用时运行它:

Action special;
if (messageBehavior.TryGetValue(message.id, out special)) {
    special();
}
Run Code Online (Sandbox Code Playgroud)

如果操作需要一些特殊的上下文来运行,例如,触发了操作的消息,您可以使用Action<Message>并向其传递消息:

private static readonly IDictionary<int,Action<MyMessageType>> messageBehavior =
    new Dictionary<int,Action> {
        {153, (m) => { Console.WriteLine("Special action; message {0}", m); } },
        {154, (m) => { Console.WriteLine("Another special action ({0})", m); } }
    };
...
Action<MyMessageType> special;
if (messageBehavior.TryGetValue(message.id, out special)) {
    special(message);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果`action`很小,这是最好的选择.如果每个特殊ID都有5个以上的LOC,它可能会变得混乱. (4认同)