2012-04-20 6 views
2

私はそうのようなページにフィルタを追加する方法必要:私はフィルタのセット量を持っており、彼らはプロパティが含ま静的なクラスまたは構造体以外のものを使用すべきですか?

カタログ/サイズ - 中/色レッド/

をすぐに変更することはほとんどありません。これらのフィルタを処理するために、私は列挙型を決定しましたが、null、拡張メソッド、およびその他のプロパティを組み込む必要があったため、これは非常に狡猾です。

最後に私はこのStackoverflow answerを見て、構造体を使用することを提案しました。ここに私が組み込んだ例があります:

public struct Color 
{ 
    private int id; 
    private bool isDef; 

    private Color(int value) { id = value; isDef = true; } 
    public bool Hasvalue { get { return isDef; } } 
    public bool IsNull { get { return !isDef; } } 

    public string Name 
    { 
     get 
     { 
      switch(id) 
      { 
       case 0: return "None"; 
       case 1: return "Black"; 
       case 2: return "Blue"; 
       case 3: return "Green"; 
       case 4: return "Orange"; 
       case 5: return "Pink"; 
       case 6: return "Brown"; 
       case 7: return "White"; 
       case 8: return "Yellow"; 
       case 9: return "Gray"; 
       case 10: return "Purple"; 
       case 11: return "Red"; 
       default: return null; 
      } 
     } 
    } 

    public string Abbreviation 
    { 
     get 
     { 
      switch(id) 
      { 
       case 1: return "BK"; 
       case 2: return "BL"; 
       case 3: return "GR"; 
       case 4: return "OR"; 
       case 5: return "PK"; 
       case 6: return "BN"; 
       case 7: return "WT"; 
       case 8: return "YL"; 
       case 9: return "GY"; 
       case 10: return "PR"; 
       case 11: return "RD"; 
       default: return null; 
      } 
     } 
    } 

    public static IEnumerable<Color> GetValues() 
    { 
     yield return Color.None; 
     yield return Color.Black; 
     yield return Color.Blue; 
     yield return Color.Green; 
     yield return Color.Orange; 
     yield return Color.Pink; 
     yield return Color.Brown; 
     yield return Color.White; 
     yield return Color.Yellow; 
     yield return Color.Gray; 
     yield return Color.Purple; 
     yield return Color.Red; 
    } 

    public static Color Parse(string value) 
    { 
     if (String.IsNullOrEmpty(value)) 
      return Color.None; 
     foreach (var c in GetValues()) 
     { 
      if (String.Equals(c.Name, value, StringComparison.Ordinal)) 
       return c; 
     } 
     return Color.None; 
    } 

    public override bool Equals(object obj) 
    { 
     if(!(obj is Color)) 
      return false; 
     Color color = (Color)obj; 
     return color.Name.Equals(this.Name, StringComparison.Ordinal); 
    } 

    public static Color None = new Color(0); 
    public static Color Black = new Color(1); 
    public static Color Blue = new Color(2); 
    public static Color Green = new Color(3); 
    public static Color Orange = new Color(4); 
    public static Color Pink = new Color(5); 
    public static Color Brown = new Color(6); 
    public static Color White = new Color(7); 
    public static Color Yellow = new Color(8); 
    public static Color Gray = new Color(9); 
    public static Color Purple = new Color(10); 
    public static Color Red = new Color(11); 
} 

これらはうまくいきますが、何らかの形で正しく感じられません。たとえば、各構造体に同じコードを書く必要があります。これは多くのコードのようです。再利用可能なコードを継承したり、データを何らかの形でインターフェースに収めたりする方がはるかに簡単です。

これを行うには良い方法がありますか?私は静的クラスを使用しようとしましたが、私の構造体に似た機能を持つものを構築する方法については頭を悩ますことができませんでした。

申し訳ありません申し訳ありませんが、私が投稿することができないようであれば、初めてのことです。

+0

structはokです(小さくて不変で、GetHashCodeと==もありません)。しかし、あなたが表示していない他のコードに問題があるように見えるので、何かを提案するのは難しいです。質問に投稿するには、この色のコードの90%を安全に切断することができます。 –

+0

フィルターコードを教えてください。ところで、なぜあなたは 'System.Drawing.Color'を使用していませんか? –

+0

私は文句が混乱につながったと思います。私のフィルタコードは問題ありません。同じコードをたくさん書くことについての部分は、構造体そのものを参照していました。ほとんど同じコードを持つ6つの長い構造体を書くことは少し非効率的であるように見えました。 – Eco

答えて

3

あなたは色の列挙と正しいクラスのインポートとapprev-カラーマッピング

スタート用の辞書をお勧めします:

using System.Collections.Generic; 

は、すべてを含む列挙型を作成します。可能な色:

enum Colors : uint 
{ 
    Black = 0x00000000, 
    Blue = 0x0000FF00, 
    Green = 0x00FF0000, 
    Orange = 0xFFA50000, 
    Pink = 0xFFC0CB00, 
    Brown = 0xA52A2A00, 
    White = 0xFFFFFF00, 
    Yellow = 0xFFFF0000, 
    Gray = 0x80808000, 
    Purple = 0x80008000, 
    Red = 0xFF000000 
}; 

注:RGBA [rrggbbaa]またはRed | Green | Blue | Alphaは00-FF(0-255)の任意の値を取ることができます。

次に色値の1対多の関係をマッピングするための辞書を使用します。

private Dictionary<string, Colors> colorMap = new Dictionary<string, Colors>(); 
colorMap.Add("None", Colors.None); 
colorMap.Add("Black", Colors.Black); 
colorMap.Add("BK", Colors.Black); 
colorMap.Add("Blue", Colors.Blue); 
colorMap.Add("BL", Colors.Blue); 
colorMap.Add("Green", Colors.Green); 
colorMap.Add("GR", Colors.Green); 
colorMap.Add("Orange", Colors.Orange); 
colorMap.Add("OR", Colors.Orange); 
colorMap.Add("Pink", Colors.Pink); 
colorMap.Add("PK", Colors.Pink); 
colorMap.Add("Brown", Colors.Brown); 
colorMap.Add("BN", Colors.Brown); 
colorMap.Add("White", Colors.White); 
colorMap.Add("WT", Colors.White); 
colorMap.Add("Yellow", Colors.Yellow); 
colorMap.Add("YL", Colors.Yellow); 
colorMap.Add("Gray", Colors.Gray); 
colorMap.Add("Grey", Colors.Gray); 
colorMap.Add("GY", Colors.Gray); 
colorMap.Add("Purple", Colors.Purple); 
colorMap.Add("PR", Colors.Purple); 
colorMap.Add("Red", Colors.Red); 
colorMap.Add("RD", Colors.Red); 

とマッピングのための辞書検索方法:

public Color GetColor(string colorName) 
{ 
    Color color = null; 
    if (this.colormap.TryGetValue(colorName, out color)); 
    return color; 
} 

注意:入力と出力のタイプが異なるため、プロパティを使用することはできません。

TryGetValue()は辞書検索を行います。 TryGetValue()はGetValue()よりも優先されます。なぜなら、キーを見つけられなかった場合は、何もしません(デフォルトで 'color'を最初に設定したものになります)。代替メソッド(GetValue())は、キャッチする

ボーナス:

を私はあなたがそれを見つけることができるかどうか、マッピングに別の値を追加しました。値をマッピングするメリットは、拡張性が高いことです(追加するのは簡単です)。あなたは脆弱な構造に自分自身をロックしていません。

免責事項:

掲載され、このコードが正確に動作しない場合がありますので、私は約一年でのC#の行を書いていません。うまくいけば、バグがあれば、私は何を意味するのかを伝える良い仕事をしました。

更新:

私は列挙型にRGBA値を追加することにしました。もしあなたがまだ分かっていないのであれば、デフォルトで列挙型のenumは、intが自動生成される '辞書'のようなものです。その型を変更し、値を定義することによって、使用可能な値(この場合は「辞書」)にキャストできます。

は、列挙型の値から色の名前がそれをキャストするのと同じくらい簡単です行き方:

string colorName = "Gray"; 
Colors color = GetColor(colorName); 
if(colorName != null) 
{ 
    uint colorHex = (uint)color; 
} 

注:私はcolorHexを印刷するだろうが、適切にフォーマットされず、それはちょうど、整数値を表示します(つまり、いません16進値)。私は頭の上からテキストフォーマットをする方法を覚えていないので、私は気にするつもりはありません。他の誰かが文字列の書式を追加したい場合、私は反対しません。

アップデート2:逆引き参照

public string GetAbbrev(Colors color) 
{ 
    Dictionary<string, Colors> abbrev = this.colorMap.First(abbrev => abbrev.Value == color); 
    return abbrev.Key; 
} 

私は、この方法は逆引き参照のために働くべきだと思います。 LINQの構文を理解できない場合は、すべての辞書エントリを照会して、キーがメソッドのパラメータと一致する最初のエントリを返します。その後、そのエントリからキーが返されます。

+0

それはちょっと面白かったです。私はC#のスキルを磨いてからしばらくしています。 –

+0

興味深い。私はあなたのコードの目的は、名前または省略形のいずれかが与えられたときに、16進コードを取得することだと思います。 Color.Redの省略形やColor.Brownの名前はどうやって取得できますか?私は辞書を追加し続けることができると思うが、それは私の構造体と同じことをするだろうが、一見あまりエレガントではない。 – Eco

+0

@Eco目標ではなく、有用な副作用です。省略形が必要な場合は、辞書を値で検索して一致するキーを見つけることができます。リバースルックアップはO(n)の複雑さになります(つまり、通常のルックアップ@ O(1)と比較します)。 dict.index()を使用して最初に返された値を取得するか、1対多の関係があるため、色に一致するすべての値を返す必要があります。 「辞書を追加しておくことができると思います」質問に掲示されたコードとは異なり、1つのマップはすべての略語マッピングのバリエーションを処理する必要があります。 –

関連する問題