我需要帮助改进我的字符串格式化程序

时间:2009-08-21 13:44:04

标签: c#

我正在尝试根据类型格式化字符串...但我觉得它有点难看。有没有人有更精致的approch sugestions?

 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 :(得分: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){
    // ...
}

并且不对类型名称进行比较(或者至少,如果你这样做,请检查完全限定的类型名称,即包括命名空间)。

修改
另一种解决方案,考虑到Allon的评论,使用字典类型 - >函数:

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 :(得分: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或更高版本,我可以做得更好。

答案 2 :(得分: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();
}