2009-08-21 7 views
3

タイプに応じて文字列を書式化しようとしています...しかし、それは一種の醜いと感じます。誰もより洗練されたapprochのための任意の欲求を持っていますか?私は文字列フォーマッタを改良するのに助けが必要です

string DateFormat = "MMM dd yyyy"; 
string NumberFormat = "0.0"; 

string FormatString(Type t, object value) 
    { 
     string output = ""; 

     switch (t.Name.ToUpper()) 
     { 

      case "DATETIME": 
       output = ((DateTime)value).ToString(DateFormat); 
       break; 
      case "SINGLE": 
       output = ((Single)value).ToString(NumberFormat); 
       break; 
      case "DOUBLE": 
       output = ((Double)value).ToString(NumberFormat); 
       break; 
      default: 
       output = value.ToString(); 
       break; 
     } 

     return output; 

    } 
+0

フォーマットをCurrentCultureに設定してフォーマットを処理することはできますか? – tvanfosson

答えて

7

なぜメソッドをオーバーロードしないのですか?

using System; 

namespace test { 

    static class Formatter { 

     const string DateFormat = "MMM dd yyyy"; 
     const string NumberFormat = "0.0"; 

     public static string Format(double d) { 
      return d.ToString(NumberFormat); 
     } 

     public static string Format(DateTime d) { 
      return d.ToString(DateFormat); 
     } 

     // most generic method 
     public static string Format(object o) { 
      return o.ToString(); 
     } 

    } 

    class Program { 

     public static void Main() { 
      Console.WriteLine(Formatter.Format(2.0d)); 
      Console.WriteLine(Formatter.Format(DateTime.Now)); 
      // an integer => no specific function defined => pick the 
      // most generic overload (object) 
      Console.WriteLine(Formatter.Format(4)); 
     } 

    } 
} 

:あなたはタイプを比較する必要がある場合、あなたは

if (typeof(int) == t){ 
    // ... 
} 

を使用する必要がありますし、タイプ名に比較を行う(あるいは、少なくとも、あなたがそれを行う場合は、完全にをチェックしませんが修飾された型名、すなわち名前空間を含む)。

EDIT
辞書タイプ - >機能を使用して、アカウントにアロンさんのコメントを取る代替ソリューション、この第二の溶液で

using System; 
using System.Collections.Generic; 

namespace test { 

    public class Formatter { 

     delegate string FormatFunction(object o); 

     private string FormatDouble(object o) { 
      double d = (double)o; 
      return d.ToString("0.0"); 
     } 

     private string FormatDateTime(object o) { 
      DateTime d = (DateTime)o; 
      return d.ToString("MMM dd yyyy"); 
     } 

     // map types to format function 
     private Dictionary<Type, FormatFunction> _formatters = new Dictionary<Type, FormatFunction>(); 

     public Formatter() { 
      _formatters.Add(typeof(double), FormatDouble); 
      _formatters.Add(typeof(DateTime), FormatDateTime); 
     } 

     public string Format(object o) { 
      Type t = o.GetType(); 
      if (_formatters.ContainsKey(t)){ 
       return _formatters[t](o); 
      } else { 
       return o.ToString(); 
      } 
     } 

    } 

    class Program { 
     public static void Main() { 
      Formatter f = new Formatter(); 
      Console.WriteLine(f.Format(2.0d)); 
      Console.WriteLine(f.Format(DateTime.Now)); 
      Console.WriteLine(f.Format(4)); 
     } 
    } 
} 

を、あなたはただ持っている場合でも、正しい機能を取得オブジェクトへの参照(私は可能ならば最初の解決策を使用します)。

+1

私はこのオプションが私の一般的なソリューションよりもさらに好きです。 –

+0

ありがとう、私が今までに受け取った最高のコメント:) –

+0

このメソッドの呼び出し側がToString-edになる必要があるオブジェクト参照のみを保持している場合、これはうまくいかないが、これはうまくいかない。例えば。 void PrintDebugVar(string name、object var){Debug.WriteLine(string.Format( "{0} = {1}"、name、Formatter.Format(var))); } –

2
string Format<T>(T value) 
{ 
    Type[] numericTypes = new Type[] {typeof(double), typeof(single)}; 

    if (Array.IndexOf(numericTypes, typeof(T))) 
     return string.Format("{0:0.0}", value); 
    else if (typeof(T) is DateTime) 
     return string.Format("{0:MMM dd yyyy}", value); 
    else 
     return value.ToString(); 
} 

は、.NET 3.0以降を使用している場合、私は少しでもよりよいことを確認することができます。

+0

私はあなたが.NET 2.0以降(つまりGenerics)を意味すると信じています。 –

+0

あなたはちょうどそこに小さなlinqを振りかけることになっていたのですか? ;-) –

+0

'typeof(T)is DateTime'は常にfalseです。' T is DateTime'または 'typeof(T)== typeof(DateTime)'を意味しませんでしたか? –

0

ここで提供される他の2つのソリューションは、提供される引数の静的型に従って適切な書式設定を呼び出す必要がある場合に最適です。しかし、オブジェクトの実行時の型に従って書式設定を行う必要がある場合、それらは機能しません。あなたの最初の試みはうまくいったが、そのようにタイプを比較するのは最善の方法ではない。代わりに、 'is'キーワードを使用してください:

public static string FormatObject(object obj) 
{ 
    if (obj is DateTime) 
     return ((DateTime)obj).ToString("MMM dd yyyy"); 
    else if (obj is float || obj is double) 
     return (obj as IFormattable).ToString("0.0", new System.Globalization.NumberFormatInfo()); 
    else return obj.ToString(); 
} 
+0

実際に私が提供する2番目のソリューションは、オブジェクトの実行時の型に従って書式を設定します...何が問題なのですか? –

+0

ええええええええええええええええええええええええええええええええええええええええええええええええええええええええと解決した解決策はランタイムタイプをチェックしますしかし、それを見てください - それはむしろ(メソッドのオーバーロードを使用することを主張しているからといって)むしろ大規模で畳み込まれていることを除いて、高価である反射(.GetType())を使用し、そのような単純な問題のために、安全で、倹約的で、または誠実でもない。私がコードのようなものに遭遇すると、それが何をするかを理解するのに数分かかりますし、保守性と可読性のために私のソリューションのように書き直します。 –

+0

反射と「キーワード」の掲載結果の関連について、このリンクを含めるのを忘れてしまった:http://gabewishnie.blogspot.com/2005/10/is-and-as-lesser-known-c-keywords.html –

関連する問題