I need help with refining my string formatter
c#
Solution
Why not just overloading methods?
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));
}
}
}
NOTE: if you need to compare types, you should use
if (typeof(int) == t){
// ...
}
and not perform comparisons on the type name (or at least, if you do it, check the fully qualified type names, i.e. including the namespace).
EDIT An alternative solution, that takes into account Allon's comment, using a dictionary type->function:
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));
}
}
}
With this second solution, you get the correct function even if you just have a reference to an object (I still would use the first solution if possible).
Problem
I am trying to format strings depending on the type ...but I feel it's kind of ugly. has anyone have any sugestions for a more refined 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; } ```