2013-05-12 14 views
7

最近開発中の開発者は、通常は列挙型の代わりにクラスパターンを使用し始めました。彼の推論は、それが目に見えない列挙のように見えるということですが、彼は中に含まれる(上記IsMatchなど)命数に関連するメソッドを含めることができます列挙型ではなく、列挙型クラスをいつどのように使うべきですか?

internal class Suit 
{ 
    public static readonly Suit Hearts = new Suit(); 
    public static readonly Suit Diamonds = new Suit(); 
    public static readonly Suit Spades = new Suit(); 
    public static readonly Suit Clubs = new Suit(); 
    public static readonly Suit Joker = new Suit(); 
    private static Suit() 
    { 

    } 
    public static bool IsMatch(Suit lhs, Suit rhs) 
    { 
     return lhs.Equals(rhs) || (lhs.Equals(Joker) || rhs.Equals(Joker)); 
    } 
} 

:代わりに、彼は以下のものと同様のものを使用しています列挙自体。

彼はこれをEnumerationクラスと呼びましたが、これまでに見たことはありません。私は長所と短所がどこにあるのか、そしてどこでより多くの情報を見つけることができるのか疑問に思った。

おかげ

編集:彼は説明したもう一つの利点は、列挙のための特定のToString()の実装を追加することがされていました。

+0

まあ上で読むことができます、あなたは 'enum'でこれを行うことはできません。私はこれがこのようなものを使用する主な理由だと思いますか? –

+0

私が遭遇した唯一の本当の欠点は(それについてあまり幸せではないサードパーティ製のライブラリに加えて)あなたは(単純に)そのタイプのスイッチ/ケースを行うことができないということです。しかし、私はこの技術をC#で広範に使用していません。 –

+0

スイッチのステートメントを避けることが彼の主なセールスポイントでした。彼はそれをモノリシックスイッチのステートメントとして記述するのを避けるために使っていました。しかし、あなたが望むときでさえ、あなたがそれらを使用するのを止める点です。 –

答えて

1

列挙型の主な利点は、基本的にいくつかの名前付きの値を持つ整数であることです。そのような列挙型は本質的に移植性とシリアライズ可能です。算術演算と論理演算も列挙型で高速です。

エニュメレーションクラスは、追加の状態情報を持つ不透明な値が必要な場合に使用されます。ダル操作のユーザーに

 
public static class Dal 
{ 
    public static Record Query(Operation operation, Parameters parameters); 
} 

var result = Dal.Query(Operation.DoSomething, new DoSomethingParameters {...}); 

利用可能な操作の単なる列挙ですが、それは、接続文字列が含まれている可能性があり、SQL文またはストアド:たとえば、一般的なデータアクセス層のようなインターフェイスとして持つことができますプロシージャ、および一般的なDalに必要なその他のデータ

もう1つの「共通」は、システム(状態または戦略)のパブリックモードです。ユーザーの観点からは、このモードは不透明な値ですが、システムの実装に不可欠な情報や内部機能を含んでいる可能性があります。わかりやすい例:

 

public class TheSystem 
{ 
    public SystemMode Mode; 
    public void Save() 
    { 
     Mode.Save(); 
    } 
    public SystemDocument Read() 
    { 
     return Mode.Read(); 
    } 
} 

public abstract class SystemMode 
{ 
    public static SystemMode ReadOnly = new ReadOnlyMode(); 
    public static SystemMode ReadWrite = new ReadWriteMode(); 

    internal abstract void Save(); 
    internal abstract SystemDocument Read(); 

    private class ReadOnlyMode : SystemMode 
    { 
     internal override void Save() {...} 
     internal override SystemDocument Read() {...} 
    } 

    private class ReadWriteMode : SystemMode 
    { 
     internal override void Save() {...} 
     internal override SystemDocument Read() {...} 
    } 
} 


TheSystem.Mode = SystemMode.ReadOnly; 

単純な列挙型を使用しないIsMatch静的メソッドはありません。この場合、拡張メソッドを使用すると、非常に似たようなことが実現できます。

+0

彼らはよく使われているツールで、どこでも使用すべきではありません。ほとんどのもののように。例をありがとう。 –

1

列挙型は、軽量の状態情報に適しています。たとえば、色の列挙型(青色を除く)は、交通信号の状態を照会するのに適しています。色とそのすべての手荷物(アルファ、色空間など)の全体的なコンセプトに沿った真の色は重要ではありません、ちょうどどの状態がライトです。また、あなたの列挙型を少し変更して信号機の状態を表します:

[Flags()] 
public enum LightColors 
{ 
    unknown = 0, 
    red = 1, 
    yellow = 2, 
    green = 4, 
    green_arrow = 8 
} 

現在の光状態は、次のように設定することができる:

LightColors c = LightColors.red | LightColors.green_arrow; 

として照会:

if ((c & LightColors.red) == LightColors.red) 
    { 
     //Don't drive 
    } 
    else if ((c & LightColors.green_arrow) == LightColors.green_arrow) 
    { 
     //Turn 
    } 

静的クラスカラー部材は、この複数をサポートすることができるであろう特別な機能はありません。

しかし、静的なクラスメンバは、よく使用されるオブジェクトにとって素晴らしいです。 System.Drawing.Colorメンバーは、(16進数の色がわからない限り)あまり知られていないコンストラクタを持つ既知の名前の色を表すため、素晴らしい例です。彼らは列挙型として実装された場合は、このようにあなたが色として値を使用したいたびに何かをする必要があります:あなたが列挙型を持っているのであれば

colors c = colors.red; 
     switch (c) 
     { 
      case colors.red: 
       return System.Drawing.Color.FromArgb(255, 0, 0); 
       break; 
      case colors.green: 
       return System.Drawing.Color.FromArgb(0,255,0); 
       break; 
     } 

を、あなたは常にスイッチをやっていることを発見/ case/if/else /オブジェクトを派生させるためには、静的クラスメンバを使用することができます。あなたが何かの状態だけを照会しているのであれば、私は列挙型に固執します。また、安全でない方法でデータを渡す必要がある場合、列挙型はおそらくオブジェクトのシリアル化されたバージョンよりも優れています。このフォーラムから古いポストフォーム

参照: When to use enums, and when to replace them with a class with static members?

+0

この投稿は、私が探していたものと非常によく似ています。フレームワークの良い例です。ありがとう –

4

列挙型は、他の人にシナリオの多くでうまく、しかし非常に悪いです。通常、私は列挙型といくつかの問題 を見つける:列挙に関連

  • 行動
  • 新しい列挙値は、ショットガンの手術を必要とするアプリケーションに散らばっます
  • 列挙型は、オープン・クローズ原理
に従いません

エニュメレーションの振る舞いが散在しているため、エニュメレーションタイプには何の振る舞いもできないため、元の型に戻すことはできません。 列挙クラス有する一方で

各列挙型のバリエーションのすべてが列挙クラスが、各特定のサブタイプのみならずプッシュダウンすることができます。

列挙型はさまざまなシナリオでうまく機能しますが、ドメインモデル内ですばやく機能します。 Enumerationクラスは、同じ使い勝手の多くを提供し、動作の宛先になるという追加の利点があります。

スイッチのステートメントは不要です。その変数と属している知識をモデル内に戻すことができます。何らかの理由で特定の列挙クラス値をチェックする必要がある場合、そのオプションはまだ私のために開かれています。このパターンはすべての列挙を置き換えるべきではありませんが、代わりの方法があるのは良いことです。あなたは複合型に列挙型を入力することはできませんので

はそのhere