2009-08-21 3 views

답변

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){ 
    // ... 
} 

를 사용해야하고, 유형 이름에 비교를 수행 (또는 적어도, 당신이 그것을 할 경우, 완전히 을 확인하지를 자격이 부여 된 유형 이름 (예 : 네임 스페이스 포함).

편집
기능> 유형 - 사전 사용, 계정 알론의 의견을 고려한 대안 솔루션 :이 두 번째 솔루션으로

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

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; 

    } 
당신은 닷넷 3.0을 사용하고있는 이상 내가 조금이라도 더 좋은 것을 확인 할 수 있습니다.

+0

.NET 2.0 이상 (예 : Generics)을 의미한다고 생각합니다. –

+0

거기에 약간의 린크를 뿌리고 싶었던 거지? ;-) –

+0

'typeof (T) is DateTime'은 항상 거짓 일 것입니다.'T is DateTime' 또는'typeof (T) == typeof (DateTime)'을 의미하지 않았습니까? –

0

제공된 두 개의 다른 솔루션은 제공된 인수의 정적 유형에 따라 적절한 형식을 호출해야하는 경우에 유용합니다. 그러나 객체의 런타임 유형에 따라 형식을 지정해야하는 경우에는 작동하지 않습니다. 원래의 시도는 좋았지 만, 그런 식으로 유형을 비교하는 것이 최선의 방법은 아닙니다. 대신에 '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

사실 내가 제공 한 두 번째 솔루션은 객체의 런타임 유형에 따라 서식을 지정하는데 ... 그게 뭐가 잘못 되었나요? –

+0

그래, 편집 한 솔루션은 런타임 유형을 확인하지. 그러나 그것을 봐라. - 당신이 메소드 오버로드를 사용하기를 주장하기 때문에 그것이 크고 복잡하다는 사실을 제외하고는 비싸고 (* .GetType()) 리플렉션을 사용하고 스레드가 아닌 공유 상태를 저장하고 유지한다. 그러한 단순한 문제에 대해 안전하고 검소하며 심지어 제정신이 아닙니다.코드에서 이와 비슷한 문제가 발생한다면, 그것이 무엇을하는지 깨닫기까지 몇 분이 걸릴 것입니다. 그리고 유지 보수성과 가독성을 위해 솔루션으로 다시 작성하겠습니다. –

+0

리플렉션 대 '관련'키워드 실적에 대한 링크를 포함하는 것을 잊어 버렸습니다. http://gabewishnie.blogspot.com/2005/10/is-and-as-lesser-known-c-keywords.html –

관련 문제