1

私が書いているプログラムのさまざまな部分の間でメッセージを送信するシステムを実装しています。一般的なメッセージ タイプと、プログラムの各部分に固有のメッセージ タイプがあります。各タイプの基本メッセージ クラスから派生することに固有の階層の腐敗を回避したいので、このタイプを 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 型を 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

それらを数値のままにしておきたい場合、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

「コマンド」と「メッセージ」の違いを調べることをお勧めします。これは、メッセージ内でのマジック ナンバー\列挙の使用は悪い考えであるという結論に達するのに役立つかもしれません。

理想的には、リスナーによって監視および実行される「コマンド」を作成する必要があります...

HTH

オリー

于 2009-09-02T09:39:09.023 に答える
0

本当にこれを行いたい場合は、可能なすべての値を保持する 1 つのジェネリック プライベート 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 に答える