C#中的可切换唯一标识符

时间:2009-09-02 05:38:35

标签: c# const uniqueidentifier switch-statement

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

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()函数初始化,但如果我这样做,我无法切换()传递的Message类型,因为它说“预期的常量类型”对于每个案例。

6 个答案:

答案 0 :(得分: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();

答案 1 :(得分:1)

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

答案 2 :(得分: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...
    }

}

然后你只需要确保你保持每种类型的消息的边界。

答案 3 :(得分:1)

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

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

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

因此,您可以将所有特定枚举从上一个枚举集的值开始,并将其构建为这样。

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

尽管在这种情况下似乎继承可能是不可避免的,因为数据模型中存在自然的层次结构。

答案 4 :(得分:0)

我建议你查找'command'和&amp; '消息',这可能会帮助你得出结论,在消息中使用魔术数字\枚举是一个坏主意。

理想情况下,您希望创建由侦听器观察和操作的“命令”......

HTH

奥利

答案 5 :(得分:0)

如果你确实想要这样做,你可以创建一个包含所有可能值的通用私有枚举。

然后,您可以通过单独的类将这些值公开为只读属性,将枚举公开为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 ; }
        }
    }
}

然而 - 我建议你重新设计你的解决方案。这似乎是在寻找麻烦(因为我相信人们会发表评论)