2009-06-26 4 views
6

私は最近、曖昧に長い文をswitchステートメントとenum宣言をC#コードで定義する必要があることを知りましたが、論理サブセクションに分割する最良の方法は何かと思います。私の状況では、列挙型の値とケース(列挙型の値に基づいている)はかなり明確なグループ分けをしていますが、これをコードに反映させる方法は少し不明です。長いswitch/enum宣言内の領域を使用しますか?

私のコードでは、約10〜30のenum値/ケースのグループが約5つあります。

私が考えることができる3つの漠然と賢明なオプションは次のとおり

  1. は、(必要に応じて空白行で区切られた)宣言内ケース/ enum値のすべての論理グループの周りに#regionブロックを定義します。
  2. 各グループの名前の前に空白行を付けて、各グループに名前を付けます。
  3. 何もしないでください。switch/enumを大量のケース/値リストとして残してください。

どちらをお好みですか?列挙型とスイッチを別々に扱いますか?(これは私にはやや奇妙に思えるかもしれません)今、私は、この質問に正解/間違った答えがあるとは言いませんが、それでも意見の一般的な合意が何であるかを聞くことにはかなり関心があります。

注1:私はレクサー(トークナイザ)を書き込もうとしていますので、私は潜在的な値+ 100分の50の非常に長い列挙型の宣言がある場合があります。このような状況は、残念ながら避けられない(と同様にスイッチ付き)で、したがって、これはいくつかの理由から最も合理的なアプローチと思われる。

注2:私はいくつかの重複した質問が既に(主に、構造化クラスのため)一般のコード内の領域を使用するかどうかの問題に存在していることを十分に承知していますが、私はここに私の質問は、はるかに具体的かつhasnであると感じまだ対処されていません。

+0

ただ私の答えを編集しました。それが助けて欲しいと思っています:) –

答えて

3

確かに、これらの事柄を上げてください。おそらくそれほど変わることはないでしょうし、そうしたときにリージョンを拡張したり、変更したり、折りたたんだり、残りのファイルに移動したりすることができます。

彼らは理由のためにそこにあなたの利点のためにそれらを使用します。

+0

これは私がこの質問をする前の私の思考でした。私は地域の過度の使用をいくらか「悪」とみなす傾向がありますが、これは例外的なようです。 – Noldorin

1

大量のケース/値のリストとして残しておきます。

+0

あなたは一般的に地域が好きではないという理由があります。 (これは公正なポイントかもしれません) – Noldorin

+0

+1私は地域別名コード難読化が嫌いです。 – kenny

+0

私は一般的にまたはこの特定のインスタンスでは地域が好きではありません:)。私はctrl + m + oを使用してクラスファイルを折りたたむのが好きです。リージョンはコードの代わりに表示されるため、リージョンが意図を破ります。 –

0

列挙型を取り除き、オブジェクトにする。その後、オブジェクト上のメソッドを呼び出し、コードを分離して保守しておき、悪夢ではないようにすることができます。

実際にはオブジェクトの代わりにenumを使用する必要があり、長いswitch文が好きな人はほとんどいません。

+0

私の最初のメモを参照してください。これは私が書いている(コンパイラの一部としての)レクサーです。私が既存のコードで見た唯一のアプローチは、列挙型を使用することです - これらの例は、通常、非常に単純な文法のために定義されているため、実際にはグループ化は必要ありませんでした。 – Noldorin

+0

私の答えが変わるとは思わない。ソースを見ずに、私はそれらを価値オブジェクトに分解することができると信じなければなりません。 –

+0

残念ながら、私は本当に何らかの種類の単一のデータ構造で値を指定する必要があります。私は列挙型がレクサーの "トークンの種類"を表し、トークン構造体に格納されなければならないと述べたはずです。 – Noldorin

1

ストラテジーデザインパターンを使用して同じコードブロックを持つケースがある場合は、スイッチブロックを削除できます。これは、あなたに多くのクラスを作成することができますが、実際の複雑さを示し、より小さなクラスでロジックを分割します。

+0

興味深い提案。私は戦略パターンに精通していません。私の列挙型が一連のトークン型を表す場合(そして私はこれをコンパイラ用に書いています)、ここで本当に関係していますか? – Noldorin

+0

そこに戦略を使用することに大きな問題はありません。 基本的には、各ケースブロック内でロジックを実行する責任を持つクラスを作成します。これは、使用するロジッククラスを定義するより大きなクラス(スイッチblcokを持つクラス)をインスタンス化する人です。 – mkato

3

また、辞書< [your_enum_type]、アクション>(またはアクションの代わりにFunc)などを使用することもできます(機能に似た署名があるとみなして)。そして、あなたはできる代わりの代わりに、スイッチを使用して:

 switch (item) 
     { 
      case Enum1: func1(par1, par2) 
       break; 
      case Enum2: func2(par1, par2) 
       break; 
     } 

あなたはのようなものかもしれない:

public class MyClass 
{ 
    Dictionary<int, Action<int, int>> myDictionary; 
    //These could have only static methods also 
    Group1Object myObject1; 
    Group2Object myObject2; 

    public MyClass() 
    { 
     //Again, you wouldn't have to initialize if the functions in them were static 
     myObject1 = new Group1Object(); 
     myObject2 = new Group2Object(); 
     BuildMyDictionary(); 
    } 

    private Dictionary<int, Action<int, int>> BuildMyDictionary() 
    { 
     InsertGroup1Functions(); 
     InsertGroup2Functions(); 
     //... 
    } 

    private void InsertGroup2Functions() 
    { 
     myDictionary.Add(1, group2.AnAction2); 
     myDictionary.Add(2, group2.AnotherAction2); 
    } 

    private void InsertGroup1Functions() 
    { 
     myDictionary.Add(3, group1.AnAction1); 
     myDictionary.Add(4, group1.AnotherAction1); 
    } 


    public void DoStuff() 
    { 
     int t = 3; //Get it from wherever 
     //instead of switch 
     myDictionary[t](arg1, arg2); 
    } 
} 
+0

この方法は、多くの状況(特にロングケースブロック)で利点があります。しかし、私にとっては、これは実際にswitch文を辞書に追加するメソッドに延期するだけであり、実際にはグループ化に役立たない。 – Noldorin

+0

IMHOこれはまったく同じではありません。これは、辞書を追加する行を複数のメソッドに分割するのに便利です。また、デリゲートによる抽象度のレベルも向上します。デリゲートをコード内のどこからでもリストに追加できます。 – Groo

+0

@samuel:サンプルコードを追加していただきありがとうございます。実際、辞書の初期化をメソッドに分割する方法は非常に有利です。私は今このソリューションが好きです。 :) – Noldorin

0

をここで領域を使用する人のための良いショートカットです。

私は

Ctrl-M-M

を押すとLOでVSでフルスクリーンに行くと、見よしようとしたとき、私はEclipseとVisual Studioの間で切り替えた、領域が閉じて拡大!

+0

ええ、便利なショートカットがあります。これは、リージョンを潜在的に可能性のあるものよりも迷惑にならないようにすると思います。 :) – Noldorin

関連する問題