Really new to this, but trying to implement a CustomFormater class ICustomFormatter
The idea is pretty simple but I cannot get it to work without adding hundred of if
statements.
Format "K" should output the value divided by 1024, but whatever that value type
is, it could be a int
, ulong
, decimal
and so on, any value that implements INumeric
public class myFormatter : IFormatProvider, ICustomFormatter {
public object? GetFormat(Type? formatType) => formatType == typeof(ICustomFormatter) ? this : null;
public string Format(string? format, object? arg, IFormatProvider? formatProvider) {
formatProvider ??= this;
if (!Equals(formatProvider)) return string.Empty;
if (arg == null) return string.Empty;
string resultString = arg.ToString() ?? "";
if (format.StartsWith('K')) {
resultString = string.Format("{0:#,0.0} {1}", (double)arg / 1024, format);
}
return resultString;
}
}
But as you could guess, it throws InvalidCastException
when arg cannot be converted to double
. How do I make it generic? for any given value it would always be divisible by 1024 right?
var fp = new myFormatter();
Debug.WriteLine($"{fp.Format("K", 1024d, fp)}"); // Works fine
Debug.WriteLine($"{fp.Format("K", 1024, fp)}"); // Fails
PS: And yes, I know there are several diff types to convert a number to K and classes/helpers for it, but I just need this simple one and I will implement other formats on my formatter as well.
You can't "cast" an object
to double
unless the underlying value is actually a double. The same syntax is used for conversion if the variable type is implicitly convertible, but there is no implicit conversion from object
to double
Convert.ToDouble
can convert at runtime, though:
if (format.StartsWith('K')) {
resultString = string.Format("{0:#,0.0} {1}", Convert.ToDouble(arg) / 1024d, format);
}
Now the conversion will happen at runtime, and will fail if the value cannot be converted (e.g. a string value that does not represent a valid number). You'll have to decide how to deal with those cases.
Note that I changed the denominator to a double value also to make the math more straightforward.