C# 自定义格式化字符串说明符

来源:互联网 发布:什么微单最好 一款知 编辑:程序博客网 时间:2024/05/21 08:47

大家好,今天我将为大家介绍 C# 中如何自定义格式化字符串说明符。

 

编程时候经常会用到 Console.WriteLine() 这个函数,其中必不可少的就是各种各样的格式化说明符,他们负责将要输出的字符串以各种形式输出。但毕竟 C# 中定义好的格式化说明符有限,不能满足所有人的需求,因此,自定义格式化说明符就显得有必要了。

 

在学习之前,有必要先了解一下 Console.WriteLine() 函数的工作方式。

 

实际上,Console.WriteLine() 函数会将其所有的参数传递给静态方法 String.Format() ,然后由该函数进行格式说明符的转换。

 

String.Format() 形式如下:

 

string.Format(this.FormatProvider ,format ,neW object[](argO ,arg1....))

 

示例:

 

Console.WriteLine("hello world {0:E}", 123);

 

运行结果为:hello world 1.230000E+002

因为 "E" 表示以科学计数法表示 123 这个数而且结果的 "E" 大写。而 Console.WriteLine() 将所有参数(此例中为两个)传递给 String.Format() 方法, 该方法负责把格式化说明符转换为相应的格式,从而构造出最终的结果。

 

但构造的过程不是创建一个 String 类的实例,而是一个 StringBuilder 类的实例(因为这个过程需要不断改写这个字符串实例,而 String 是不可变类型,每次改变都要创造一个新的字符串,会有额外的消耗,因此用 StringBuilder 类的实例,该类是专门应对需要更改字符串的情况的,详情请参阅 MSDN)。

 

在构造的过程中,会先创建一个 StringBuilder 实例,并初始化为 "hello world"(实际上是初始化到第一个花括号前),然后不断调用静态方法 StringBuilder.Append() 和 StringBuilder.AppendFormat() 。前者负责花括号之前的字符串添加,后者负责对花括号的内容进行转换。

 

而 StringBuilder.AppendFormat() 方法执行时会先检查存储值的对象是否实现 IFormattable 接口,如果实现了该接口,则会调用该接口提供的具有2个参数的方法 ToString() 。该接口定义如下:

 

interface IFormattable{    string ToString(string format,IFormatProvider formatProvider)}

 

其中 format 就是格式化说明符,而 formatProvider 主要是用于提供背景文化信息,如果为空,则是系统默认的背景文化信息,此处不深究。

 

内置的类型都实现这个接口,可以对字符串进行格式化,如果是自己定义的类(结构体也可),则需要实现这个接口,才可以进行格式化,若不实现这个接口,则只能调用对象本身的 ToString() 方法。

 

最后,ToString() 方法会返回一个字符串,代替原来的花括号内容。

 

下面用一个坐标示例来演示:

 

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace StringFormat{    class Program    {        static void Main(string[] args)        {            //开始测试,类定义在下面            
    Vector v = new Vector(3, 2, 4);            Console.WriteLine("以 xI+yJ+zK 的格式显示");            Console.WriteLine("{0:V}", v);            Console.WriteLine("以 xi+yj+zk 的格式显示");            Console.WriteLine("{0:v}", v);            Console.WriteLine("以数字形式显示");            Console.WriteLine("{0:N}", v);            Console.WriteLine("以数字形式显示");            Console.WriteLine("{0:n}", v);            Console.WriteLine("以大写 E 科学计数法显示");            Console.WriteLine("{0:EE}", v);            Console.WriteLine("以小写 e 科学计数法显示");            Console.WriteLine("{0:ee}", v);            Console.WriteLine("对象默认的 ToStrin() 方法显示");            Console.WriteLine("{0:a}", v);            Console.ReadKey();        }    }    //定义Vector类,实现IFomattable接口    class Vector:IFormattable    {        double x, y, z; //定义三个坐标        //构造函数        public Vector(double x, double y, double z)         {            this.x = x;            this.y = y;            this.z = z;        }        //实现带有两个参数的ToString()方法        public String ToString(String format, IFormatProvider formatProvide)        {            //根据format的值决定如何显示            switch (format)            {                //以 xI+yJ+zK 的格式显示                case "V":                    StringBuilder sbV = new StringBuilder(x.ToString(), 30);                    sbV.Append("I + ");                    sbV.Append(y.ToString());                    sbV.Append("J + ");                    sbV.Append(z.ToString());                    sbV.Append("K");                    return sbV.ToString();                //以 xi+yj+zk 的格式显示                case "v":                    StringBuilder sbv = new StringBuilder(this.x.ToString(), 30);                    sbv.Append("i + ");                    sbv.Append(this.y.ToString());                    sbv.Append("j + ");                    sbv.Append(this.z.ToString());                    sbv.Append("k");                    return sbv.ToString();                                //以数字形式显示                case "N":                case "n":                   return String.Format("({0} ,{1}, {2})", x, y, z);                                //以大写 E 科学计数法显示                case "EE":                    return String.Format("{0:E} ,{1:E} ,{2:E}", x, y, z);                //以小写 e 科学计数法显示                case "ee":                    return String.Format("{0:e} ,{1:e} ,{2:e}", x, y, z);                                //对象默认的 ToStrin() 方法显示                default:                    return ToString();            }        }    }}


运行结果为:

 

 

本文就到此结束了,欢迎大家批评指正,一起交流!

 

Rember ,You Make Luck !