2009-09-02 15 views
1

私が書いているプログラムの異なる部分間でメッセージを送るシステムを実装しています。いくつかの一般的なメッセージタイプと、プログラムの各部に固有のメッセージタイプがあります。私は、各タイプの基本メッセージクラスから派生する階層的な腐敗を避けたいと思います。だから、このタイプをintまたはushortにカプセル化しています。次に、 "Messages"名前空間とさまざまな定数を持つ静的クラスを使ってさまざまな型を集中させます。しかし、私はそれぞれ異なるセクションに一意の番号のリストを維持することの問題に遭遇した:Cでの切り替え可能なユニークな識別子

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は、私はいくつかを持っている場合は特に、困難であると考えられることを持ってこれらは、衝突がないことを確認するために維持し更新することは苦痛であるようです。これに対する各参照が一意であることを確認するための簡単な解決法はありますか?静的なreadonlyを使用して、静的なコンストラクタでUnique.ID()関数を初期化しようとしましたが、これを行うと、渡されたメッセージタイプに対してswitch()を実行できません。それぞれの場合について。

+0

オブジェクトを持っているだけで何が問題になりますか? public static readonlyオブジェクトAddGraphic = new object()、それぞれは一意になります(ランタイム内で少なくとも)? – meandmycode

+0

読み取り専用の値に基づいて切り替えることはできません。私はとにかくデザインを考え直しています。 – Quantumplation

答えて

7

enumを使用していない理由はありますか?

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

- 編集:あなたは、クラスごとに番号範囲を使用することができます

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(); 
+0

列挙型では、異なるメッセージタイプの宣言を「シャード」することはできません。 switch(message.Type) { case Messages.Generic.Initialize:break; case Messages.Graphics.AddGraphic:break; } – Quantumplation

+0

(奇妙なことにフォーマットが変わってきましたが、私はあなたがアイデアを得ていると確信しています) – Quantumplation

+0

あなたの投稿では、クラスの階層は欲しくないと言いました。正直言って、あなたのswitch文がそれほど大きければ、おそらくあなたのデザインをより多くのものにする方法について考えるべきだと言いたいと思います。 –

1

私のコメントにエラボレーション、

enum MessageType 
{ 
    Update, 
    Delete, 
    Destroy 
} 

MessageType t = ...; 

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

バーサス考えてみましょう。クラスのベース番号を定義し、そのベース番号に0,1,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... 
    } 

} 

は、次に、あなたはちょうどあなたがメッセージの種類ごとに境界内に維持することを確認する必要があります。

1

これは自動ではありませんが、どこにでも値をコピー後、維持するために少し簡単かもしれ:、あなたは特定の列挙型のすべてを持つことができ

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

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

をだから、前回列挙型の値で始まるをそれを設定して構築してください。

実際のオブジェクトでは、それらをintとして格納し、あらゆるenum値を適切なintに変換することができます。

あなたのデータモデルには自然な階層があるので、このケースでは継承は避けられないようです。

+0

AddGraphicをGeneric列挙型の別のオプションにするのはなぜですか? –

+0

Taylor:さまざまなシステムが独自のメッセージタイプを定義できるように、メッセージタイプを分散することを検討しています。 – Quantumplation

+0

@Taylorだから、彼はGeneric.ValueとGraphics.Valueの両方を同じメソッドに渡して重複する値を持たないようにすることができます(例えばGeneric.UnknownとGraphics.AddGraphicは両方とも0になります) –

0

'command' & 'message'の違いを調べることをお勧めします。これは、メッセージ内のマジックナンバー\ enumsの使用が悪い考えであるという結論に至るのに役立ちます。

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

HTH

Ollie第

0

あなたは本当に、本当にこれを実行したい場合は、可能なすべての値を保持している1つの汎用のプライベート列挙型を作成することができます。

これらの値を読み込み専用のプロパティとして別々のクラスに公開すると、列挙型をInt32として公開することができます。

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 ; } 
     } 
    } 
} 

ただし、ソリューションを再設計することをおすすめします。これはトラブルを求めているようです(人々がコメントしてくれると確信しています)

+0

はい。私は、 "SystemID"と "CommandID"(00010000 && 0001)を一緒に&&でIDを作成すると思っています。つまり、私が好きな再設計された解決策が見つからなければ。 – Quantumplation

関連する問題