C# 如何将Rect转换为字符串,同时限制小数位数?

C# 如何将Rect转换为字符串,同时限制小数位数?,c#,tostring,rect,C#,Tostring,Rect,是否有一个简单的格式提供程序可以返回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 注意:我不在乎舍入,舍入或截断都可以。一个可能的

是否有一个简单的格式提供程序可以返回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

注意:我不在乎舍入,舍入或截断都可以。

一个可能的解决方案是实现您自己的自定义格式提供程序,这样您就可以使用rect对象的标准
ToString
方法。为此,您需要定义一个实现和的自定义格式化程序类。这样,您就可以实现自己的
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
方法


在这种情况下,您需要决定哪个解决方案更适合您。

您可以创建一个扩展方法:

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.toString()


别忘了包括扩展方法的名称空间

我不知道这可能是最近的发展,但到今天为止,它工作得完美无缺:

$"rect={rect:F2}"
当然,旧的
String.Format
方法也会这样做

String.Format("{0:F2}", rect);

你不能在将数字分配给Rect对象时对其进行四舍五入吗?@patsy,谢谢,但我真的不想失去数值的精度。只是用户不需要看到可能的数字。我已经更新了答案,因此可以直接使用
Rect.ToString
方法(使用自定义格式设置程序)返回您想要的结果。我喜欢这种方法。我希望有一种更少的、暴力的方法,但这是生活。我不想明确地四舍五入,而只是建议
{0:F2}