ฉันรู้ว่านี่เป็นหัวข้อเก่า แต่ฉันต้องทำเช่นนี้ string.format
ในขณะที่อีกแนวทางที่นี่ทำงานผมอยากเป็นวิธีที่ง่ายที่จะสามารถส่งผลกระทบต่อมากโทรไป ดังนั้นการเพิ่มการเรียกMath.Truncate
เข้าทั้งหมดจึงไม่ใช่ตัวเลือกที่ดีจริงๆ นอกจากนี้เนื่องจากการจัดรูปแบบบางอย่างถูกเก็บไว้ในฐานข้อมูลทำให้ยิ่งแย่ลง
ดังนั้นฉันทำผู้ให้บริการรูปแบบที่กำหนดเองซึ่งจะทำให้ฉันสามารถเพิ่มการตัดทอนลงในสตริงการจัดรูปแบบเช่น:
string.format(new FormatProvider(), "{0:T}", 1.1299); // 1.12
string.format(new FormatProvider(), "{0:T(3)", 1.12399); // 1.123
string.format(new FormatProvider(), "{0:T(1)0,000.0", 1000.9999); // 1,000.9
การใช้งานนั้นค่อนข้างง่ายและสามารถขยายได้อย่างง่ายดายตามข้อกำหนดอื่น ๆ
public class FormatProvider : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof (ICustomFormatter))
{
return this;
}
return null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (arg == null || arg.GetType() != typeof (double))
{
try
{
return HandleOtherFormats(format, arg);
}
catch (FormatException e)
{
throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
}
}
if (format.StartsWith("T"))
{
int dp = 2;
int idx = 1;
if (format.Length > 1)
{
if (format[1] == '(')
{
int closeIdx = format.IndexOf(')');
if (closeIdx > 0)
{
if (int.TryParse(format.Substring(2, closeIdx - 2), out dp))
{
idx = closeIdx + 1;
}
}
else
{
throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
}
}
}
double mult = Math.Pow(10, dp);
arg = Math.Truncate((double)arg * mult) / mult;
format = format.Substring(idx);
}
try
{
return HandleOtherFormats(format, arg);
}
catch (FormatException e)
{
throw new FormatException(string.Format("The format of '{0}' is invalid.", format));
}
}
private string HandleOtherFormats(string format, object arg)
{
if (arg is IFormattable)
{
return ((IFormattable) arg).ToString(format, CultureInfo.CurrentCulture);
}
return arg != null ? arg.ToString() : String.Empty;
}
}