1

我正在实现一个系统来在我正在编写的程序的不同部分之间发送消息。有一些通用的消息类型以及一些特定于程序每个部分的消息类型。我想避免从每种类型的基本消息类派生所固有的层次结构腐烂,所以我将这种类型封装在 int 或 ushort 中。然后,我使用“消息”命名空间和带有一堆常量的静态类来集中不同类型。但是,我遇到了必须为每个不同部分维护唯一编号列表的问题:

namespace Messages
{
    public static class Generic
    {
        public const Int32 Unknown = 0;
        public const Int32 Initialize = 1;
        ...
        public const Int32 Destroy = 10;
    }
}

然后在别处

namespace Messages
{
    public static class Graphics
    {
        public const Int32 Unknown = 0;
        public const Int32 AddGraphic = 11; // <-- ?
    }
}

拥有任意 11 个似乎很困难,特别是如果我有其中的几个,维护和更新以确保没有冲突似乎很痛苦。是否有一个简单的解决方案来确保对此的每个引用都是唯一的?我尝试使用静态只读,将它们从静态构造函数中的 Unique.ID() 函数初始化,但如果这样做,我将无法 switch() 传递的消息类型,因为它说“需要一个常量类型”对于每个案例。

4

6 回答 6

7

你不使用枚举有什么原因吗?

public enum MessageTypes
{
    Unknown,
    Initialize,
    ...
}

- 编辑:

详细说明我的评论,考虑

enum MessageType
{
    Update,
    Delete,
    Destroy
}

MessageType t = ...;

switch(t){
   case MessageType.Update:
       DoUpdate();
   }
}

相对:

interface IActionable
{
   void Do ();
}


public abstract class ActionableBase : IActionable
{
   // some other things

   public abstract void Do ();
}


public class UpdateAction : ActionableBase
{
   public override void Do ()
   {
       // Update Code
   }
}

...

IActionable a = ...;
a.Do();
于 2009-09-02T05:41:52.030 回答
1

您可以为每个类使用一个数字范围。为该类定义一个基数并将 0、1、2 等添加到该基数。

于 2009-09-02T05:42:53.930 回答
1

如果你想让它们保持数字,一种方法是将它们分成不同的大小:

namespace Messages
{
    public static class Generic
    { 
        // these messages are 3-figure numbers
        public const Int32 Unknown = 0;
        public const Int32 Initialize = 101;
        ...
        public const Int32 Destroy = 110;
    }

    public static class Graphics
    {
        // these messages are 4-figure numbers
        public const Int32 Unknown = 0;
        public const Int32 AddGraphic = 1001; // <-- ?
        // and so on...
    }

}

然后你只需要确保你保持在每种类型的消息的范围内。

于 2009-09-02T05:44:11.760 回答
1

这不是自动的,但维护起来可能会更容易,然后在任何地方复制值:

    public enum Generic
    {
        Unknown = 0,
        Initialize = 1,
        Destroy = 10
    }

    public enum Graphics
    {
        AddGraphic = Generic.Destroy + 1
    }

因此,您可以让所有特定的枚举都以先前枚举集中的值开始,然后像这样构建它们。

在您的实际对象中,您可以将它们存储为 int,并将任何枚举值转换为适当的 int。

虽然,在这种情况下,继承似乎是不可避免的,因为您的数据模型中有一个自然的层次结构。

于 2009-09-02T05:54:25.797 回答
0

我建议您查找“命令”和“消息”之间的区别,这可能会帮助您得出结论,即在消息中使用幻数\枚举是一个坏主意。

理想情况下,您希望创建由听众观察和执行的“命令”......

高温高压

奥利

于 2009-09-02T09:39:09.023 回答
0

如果您真的非常想这样做,您可以创建一个包含所有可能值的通用私有 Enum。

然后,您可以通过单独的类将这些值公开为只读属性,将枚举公开为 Int32s - 例如

namespace Messages
{
    private enum AllMessageTypes
    {
        Update,
        Delete,
        Destroy,
        AddGraphic 
    }

    public static class Generic
    {
        public Int32 Update 
        {
            get { return (Int32)AllMessageTypes.Update; }
        }
        ...
    }

    public static class Graphics
    {
        public Int32 AddGraphic 
        {
            get { return (Int32)AllMessageTypes.AddGraphic ; }
        }
    }
}

但是 - 我建议您重新设计您的解决方案。这似乎是自找麻烦(我相信人们会评论)

于 2009-09-02T09:56:43.497 回答