2009-07-09 28 views
1

さまざまな形式にエクスポートできるものがあります。現在、我々はこのような列挙型に代表されるこれらのフォーマットを持っている:変換と列挙が必要な列挙型の置換

[Flags] 
public enum ExportFormat 
{ 
    None = 0x0, 
    Csv = 0x1, 
    Tsv = 0x2, 
    Excel = 0x4, 
    All = Excel | Csv | Tsv 
} 

問題は、これらを列挙しなければならないと、彼らはまた、UIの翻訳や説明が必要だということです。現在、私は2つの拡張メソッドを作成してこれを解決しました。彼らはうまくいっていますが、私は本当にそれを好きではありませんし、解決策も全く気に入っていません。問題は、私がこれをより良くする方法を本当に分かっていないことです。誰にも良い選択肢はありますか?これらは、2つの方法です:

public static IEnumerable<ExportFormat> Formats(this ExportFormat exportFormats) 
    { 
     foreach (ExportFormat e in Enum.GetValues(typeof (ExportFormat))) 
     { 
      if (e == ExportFormat.None || e == ExportFormat.All) 
       continue; 

      if ((exportFormats & e) == e) 
       yield return e; 
     } 
    } 

    public static string Describe(this ExportFormat e) 
    { 
     var r = new List<string>(); 

     if ((e & ExportFormat.Csv) == ExportFormat.Csv) 
      r.Add("Comma Separated Values"); 

     if ((e & ExportFormat.Tsv) == ExportFormat.Tsv) 
      r.Add("Tab Separated Values"); 

     if ((e & ExportFormat.Excel) == ExportFormat.Excel) 
      r.Add("Microsoft Excel 2007"); 

     return r.Join(", "); 
    } 

これはおそらくこれを行う方法ですが、私はそれを行うためのよりよい方法が必要であると感じています。どのように私はこれをリファクタリングすることができますか?

+0

これらの文字列もローカライズする必要はありませんか?もしそうなら、それらはリソースファイルに存在しますので、コードに_anywhere_を置く必要はありません。 –

+0

真。しかし、リソースキーを列挙型に接続する何らかの方法がまだ必要です。 – Svish

答えて

5

あなたは内部のフォーマット方法を使用することができますが、このように、複数の場所ですべてのビット操作を行うことを避けるために説明:

private static Dictionary<ExportFormat, string> FormatDescriptions = 
    new Dictionary<ExportFormat,string>() 
{ 
    { ExportFormat.Csv, "Comma Separated Values" }, 
    { ExportFormat.Tsv, "Tab Separated Values" }, 
    { ExportFormat.Excel, "Microsoft Excel 2007" },    
}; 

public static string Describe(this ExportFormat e) 
{ 
    var formats = e.Formats(); 
    var descriptions = formats.Select(fmt => FormatDescriptions[fmt]); 

    return string.Join(", ", descriptions.ToArray()); 
} 

この方法は、外部ソースまたはローカライズから文字列の説明を組み込むことは容易です上記のように、

+0

スマート:) – Svish

1

唯一の他の方法は、私の心には、System.Attributeクラスの使用です。

public class FormatDescription : Attribute 
{ 
    public string Description { get; private set; } 

    public FormatDescription(string description) 
    { 
     Description = description; 
    } 
} 

[Describe]機能でReflection withを使用します。 この方法の唯一の利点は、定義と説明を1か所に持たせることです。

+0

実行時にルックアップを変更しないようにキャッシュしたい場合があり、Describeへの繰り返し呼び出しにリフレクションを使用するとコストがかかることがあります。 – adrianbanks

+0

これはローカライズするのが難しいでしょうか?私が知っている限り、属性を使うときはリソース文字列などを実際に調べることはできません。 – Svish

0

デュープ:How do I have an enum bound combobox with custom string formatting for enum values?

あなたのリソースでそれらをルックアップするために指定された属性を読み込むにTypeConverterを書くことができます。したがって、表示名の多言語サポートはあまり面倒なく行われます。

TypeConverterのConvertFrom/ConvertToメソッドを調べ、リフレクションを使用して列挙型フィールドの属性を読み取ります。

追加:

スクロールダウンリンクポストでフルサポートのために必要とされるものの一部を行うにTypeConverterの実装のために。

これは、コード名 - >英語名だけでなく、複数の言語を同時に持つアプリケーションをサポートします。

これは表示名のみであり、保存された値ではないことに注意してください。同じデータを使用する異なるロケールを持つユーザーをサポートするには、コード名または整数値を常に格納する必要があります。

+0

関連する質問(dupe、私は分かりません)にニースキャッチが、私はその質問へのより高い定評のある答えに同意する傾向があります。カスタムTypeConverterを作成すると、その列挙型が文字列としてどのように表現されるかを効果的に変更します。これにより、シリアライゼーションなどの影響が生じる可能性があります。私はGetDescriptionとNicenessComboBoxItemのアイデアが好きです。 –