Как преобразовать Rect ToString, ограничивая десятичные разряды?
Есть простой поставщик формата, который будет возвращать структуру Rect ToString
и ограничить количество знаков после запятой?
System.Windows.Rect myRect;
Если я использую myRect.ToString()
, это возвращает
myRect: 0.0139211136847734,0.109375,0.995359599590302,1
Я хочу это, ограничив число до двух десятичных знаков, но myRect.ToString("D2")
не компилируется
myRect: 0.01,0.10,0.99,1
Примечание: меня не волнует округление, округление или усечение - это нормально.
3 ответа
Вы можете создать метод расширения:
public static class RectExtensions
{
public static string ToStringRounded(this System.Windows.Rect rect)
{
return string.Format("{0},{1},{2},{3}",
Math.Round(rect.X, 2), Math.Round(rect.Y, 2),
Math.Round(rect.Width, 2), Math.Round(rect.Height, 2));
}
}
а затем позвоните myRect.ToStringRounded();
Не забудьте включить пространство имен метода расширения
Одним из возможных решений было бы внедрение собственного провайдера нестандартного формата, чтобы вы могли использовать стандартный ToString
метод прямоугольного объекта. Для этого вам нужно определить собственный класс форматера, который реализует интерфейс IFormatProvider и интерфейс ICustomFormatter. Таким образом, вы могли бы реализовать свой собственный ToString("D2")
решение. Пример решения пользовательского форматера для ваших нужд может выглядеть следующим образом:
public class CustomRectFormat : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
{
return this;
}
else
{
return null;
}
}
// the custom format
public string Format(string fmt, object arg, IFormatProvider formatProvider)
{
// the method processes every part of the Rect members
var chunk = arg.ToString();
// skip delimiters
if (chunk != ";")
{
// round doubles if possible
Double part = 0.0;
if (Double.TryParse(chunk, out part))
{
return Math.Round(part, 2).ToString();
}
}
return chunk;
}
}
Использование со стандартом Rect.ToString
метод:
var rect = new Rect();
rect.X = 0.5678;
rect.Width = 1.2345;
Console.WriteLine(rect.ToString(new CustomRectFormat()));
Вывод по желанию:
0,57;0;1,23;0
Другим возможным решением было бы реализовать свой собственный Rect
класс обертки. поскольку Rect
запечатан, он не может быть разделен на подклассы, но вы все равно можете создать класс, который имитирует исходный класс. В этом классе вы можете переписать ToString
метод с округлением:
public class CustomRect
{
private Rect rect;
public CustomRect() : this(new Size(0.0, 0.0))
{
}
public CustomRect(Size size)
{
rect = new Rect(size);
}
public Double Width
{
get { return rect.Width; }
set { rect.Width = value; }
}
public Double X
{
get { return rect.X; }
set { rect.X = value; }
}
public Double Y
{
get { return rect.Y; }
set { rect.Y = value; }
}
public Double Height
{
get { return rect.Height; }
set { rect.Height = value; }
}
public String ToString()
{
return String.Format("{0};{1};{2};{3}", Math.Round(rect.X, 2), Math.Round(rect.Y, 2), Math.Round(rect.Width, 2), Math.Round(rect.Height));
}
}
Использование класса:
var rect1 = new CustomRect();
var rect2 = new Rect();
rect1.X = 0.123;
rect1.Width = 3.2342342342342;
rect1.Height = 0.987234876234;
rect2.X = 0.123;
rect2.Width = 3.2342342342342;
rect2.Height = 0.987234876234;
Console.WriteLine(rect1.ToString());
Console.WriteLine(rect2.ToString());
И вывод:
0,12;0;3,23;1
0,123;0;3,2342342342342;0,987234876234
Это решение имеет проблему, заключающуюся в том, что вам нужно везде использовать пользовательский класс, а не предопределенный Rect
учебный класс.
Другим хорошим подходом было бы создание (как предложено @Flat Eric) метода расширения, который делает это для всех объектов Rect
учебный класс. Недостатком этого подхода является то, что вы не можете использовать ToString
метод, когда это необходимо.
Вам нужно решить, какое решение вам больше подходит в этом случае.
Возможно, это было более недавнее развитие, я не знаю, но на сегодняшний день это работает безупречно:
$"rect={rect:F2}"
Конечно, чем старше String.Format
подход будет делать то же самое.
String.Format("{0:F2}", rect);