13

職場の開発者が最近、列挙型が通常収まる場所で列挙型の代わりにクラス パターンを使用し始めました。代わりに、彼は以下のようなものを使用します。

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

彼の推論は、目に見えない列挙のように見えますが、列挙自体に含まれる列挙に関連するメソッド (上記の IsMatch など) を含めることができるというものです。

彼はこれを Enumeration クラスと呼んでいましたが、これまでに見たことのないものです。長所と短所は何か、さらに詳しい情報はどこにあるのだろうかと思いました。

ありがとう

編集: 彼が説明したもう 1 つの利点は、列挙に特定の ToString() 実装を追加できることでした。

4

3 に答える 3

4

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

列挙型クラスは、追加の状態情報を持つ不透明な値が必要な場合に使用されます。たとえば、一般的なデータ アクセス層は、次のようなインターフェイスとして持つことができます。

パブリック静的クラス Dal
{
    public static Record Query(操作操作、パラメーターパラメーター);
}

var result = Dal.Query(Operation.DoSomething, 新しい DoSomethingParameters {...});

Dal 操作のユーザーにとっては、利用可能な操作の列挙にすぎませんが、接続文字列、SQL ステートメントまたはストアド プロシージャ、および一般的な Dal が必要とするその他のデータを含めることができます。

もう 1 つの「一般的な」用途は、システム (状態または戦略) 内のパブリック モードです。ユーザーの観点から見ると、モードは不透明な値ですが、システムの実装に不可欠な情報や内部機能が含まれている場合があります。不自然な例:

パブリック クラス TheSystem
{
   public SystemMode モード。
   public void Save()
   {
      Mode.Save();
   }
   public SystemDocument Read()
   {
      モードを返します。
   }
}

パブリック抽象クラス SystemMode
{
   public static SystemMode ReadOnly = new ReadOnlyMode();
   public static SystemMode ReadWrite = new ReadWriteMode();

   内部抽象 void Save();
   内部抽象 SystemDocument Read();

   プライベート クラス ReadOnlyMode : SystemMode
   {
      内部オーバーライド void Save() {...}
      内部オーバーライド SystemDocument Read() {...}
   }

   プライベート クラス ReadWriteMode : SystemMode
   {
      内部オーバーライド void Save() {...}
      内部オーバーライド SystemDocument Read() {...}
   }
}


TheSystem.Mode = SystemMode.ReadOnly;

IsMatch 静的メソッドを持っているだけでは、単純な列挙型を使用しないことが保証されるとは思いません。この場合、拡張メソッドを使用して非常によく似たことが実現できます。

于 2013-05-12T13:10:12.137 に答える
3

列挙型は、軽量の状態情報に最適です。たとえば、色の列挙型 (青を除く) は、信号機の状態を照会するのに適しています。色の概念全体とそのすべての手荷物 (アルファ、色空間など) を含む真の色は問題ではありません。ライトがどの状態にあるかだけです。また、列挙型を少し変更して、信号機の状態を表します。 :

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

したがって、列挙型を取得していて、オブジェクトを派生させるために switch/case/if/else/whatever を常に実行していることがわかった場合は、静的クラス メンバーを使用することをお勧めします。何かの状態のみを照会している場合は、列挙型に固執します。また、安全でない方法でデータを渡す必要がある場合は、オブジェクトのシリアル化されたバージョンよりも列挙型の方がおそらくうまく機能します。

このフォーラムからの古い投稿を参照してください: 列挙型を使用する場合、それらを静的メンバーを持つクラスに置き換える場合は?

于 2013-05-12T13:21:08.473 に答える