分享

C#复合格式化

 跳跳图书馆502 2012-08-02
复合格式化
Silverlight
Composite Formatting

The .NET Framework composite formatting feature takes a list of objects and a composite format string as input. A composite format string consists of fixed text intermixed with indexed placeholders, called format items, that correspond to the objects in the list. The formatting operation yields a result string that consists of the original fixed text intermixed with the string representation of the objects in the list.

The composite formatting feature is supported by methods such as Format and AppendFormat. The String..::.Format method yields a formatted result string, and the AppendFormat method appends a formatted result string to a StringBuilder object.

A composite format string and object list are used as arguments of methods that support the composite formatting feature. A composite format string consists of zero or more runs of fixed text intermixed with one or more format items. The fixed text is any string that you choose, and each format item corresponds to an object or boxed structure in the list. The composite formatting feature returns a new result string where each format item is replaced by the string representation of the corresponding object in the list.

Consider the following Format code fragment.

Visual Basic
Dim myName As String = "Fred"
String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now)
string myName = "Fred";
String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now);

The fixed text is "Name = " and ", hours = ". The format items are "{0}", whose index is 0, which corresponds to the object myName, and "{1:hh}", whose index is 1, which corresponds to the object DateTime.Now.

Each format item takes the following form and consists of the following components:

{index[,alignment][:formatString]}

The matching braces ("{" and "}") are required.

Index Component

The mandatory index component, also called a parameter specifier, is a number starting from 0 that identifies a corresponding item in the list of objects. That is, the format item whose parameter specifier is 0 formats the first object in the list, the format item whose parameter specifier is 1 formats the second object in the list, and so on.

Multiple format items can refer to the same element in the list of objects by specifying the same parameter specifier. For example, you can format the same numeric value in hexadecimal, scientific, and number format by specifying a composite format string like this: "{0:X} {0:E} {0:N}".

Each format item can refer to any object in the list. For example, if there are three objects, you can format the second, first, and third object by specifying a composite format string like this: "{1} {0} {2}". An object that is not referenced by a format item is ignored. A runtime exception results if a parameter specifier designates an item outside the bounds of the list of objects.

Alignment Component

The optional alignment component is a signed integer indicating the preferred formatted field width. If the value of alignment is less than the length of the formatted string, alignment is ignored and the length of the formatted string is used as the field width. The formatted data in the field is right-aligned if alignment is positive and left-aligned if alignment is negative. If padding is necessary, white space is used. The comma is required if alignment is specified.

Format String Component

The optional formatString component is a format string that is appropriate for the type of object being formatted. Specify a standard numeric format string or a custom numeric format string if the corresponding object is a numeric value, a standard date and time format string or a custom date and time format string if the corresponding object is a DateTime or a DateTimeOffset object, or an enumeration format string if the corrersponding object is an enumeration value. If formatString is not specified, the general ("G") format specifier for a numeric, date and time, or enumeration type is used. The colon is required if formatString is specified.

Escaping Braces

Opening and closing braces are interpreted as starting and ending a format item. Consequently, you must use an escape sequence to display a literal opening brace or closing brace. Specify two opening braces ("{{") in the fixed text to display one opening brace ("{"), or two closing braces ("}}") to display one closing brace ("}"). Braces in a format item are interpreted sequentially in the order they are encountered. Interpreting nested braces is not supported.

The way escaped braces are interpreted can lead to unexpected results. For example, consider the format item "{{{0:D}}}", which is intended to display an opening brace, a numeric value formatted as a decimal number, and a closing brace. However, the format item is actually interpreted in the following manner:

  1. The first two opening braces ("{{") are escaped and yield one opening brace.

  2. The next three characters ("{0:") are interpreted as the start of a format item.

  3. The next character ("D") would be interpreted as the Decimal standard numeric format specifier, but the next two escaped braces ("}}") yield a single brace. Because the resulting string ("D}") is not a standard numeric format specifier, the resulting string is interpreted as a custom format string that means display the literal string "D}".

  4. The last brace ("}") is interpreted as the end of the format item.

  5. The final result that is displayed is the literal string, "{D}". The numeric value that was to be formatted is not displayed.

One way to write your code to avoid misinterpreting escaped braces and format items is to format the braces and format item separately. That is, in the first format operation display a literal opening brace, in the next operation display the result of the format item, then in the final operation display a literal closing brace. The following example illustrates this approach.

Visual Basic
Dim value As Integer = 6324
Dim output As String = String.Format("{0}{1:D}{2}", _
                                     "{", value, "}")
outputBlock.Text += output & vbCrLf
' The example displays the following output:
'       {6324}
int value = 6324;
string output = string.Format("{0}{1:D}{2}",
                             "{", value, "}");
outputBlock.Text += output + "\n";
// The example displays the following output:
//       {6324}                            

Processing Order

Each value in the parameter list that corresponds to a format item is converted to a string by performing the steps in the following list. If any condition in the first three steps is true, the string representation of the value is returned in that step, and subsequent steps are not executed.

  1. If the value to be formatted is null, an empty string ("") is returned.

  2. If the composite formatting method includes a parameter of type IFormatProvider that also implements the ICustomFormatter interface, the value is passed to the ICustomFormatter..::.Format method.

  3. If the value implements the IFormattable interface, its IFormattable..::.ToString method is called.

  4. The type's ToString method, which is either overridden or inherited from the Object class, is called.

Alignment is applied after the preceding steps have been performed.

The following example shows one string created using composite formatting and another created using an object's ToString method. Both types of formatting produce equivalent results.

Visual Basic
Dim FormatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
Dim FormatString2 As String = DateTime.Now.ToString("dddd MMMM") 
string FormatString1 = String.Format("{0:dddd MMMM}", DateTime.Now);
string FormatString2 = DateTime.Now.ToString("dddd MMMM");

Assuming that the current day is a Thursday in May, the value of both strings in the preceding example is Thursday May in the U.S. English culture.

The following example demonstrates formatting multiple objects, including formatting one object two different ways.

Visual Basic
Dim myName As String = "Fred"
String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
      myName, DateTime.Now)
string myName = "Fred";
String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
      myName, DateTime.Now);

The string value returned by the preceding code is "Name = Fred, hours = 07, minutes = 23", where the current time reflects these numbers.

The following examples demonstrate the use of alignment in formatting. The arguments that are formatted are placed between vertical bar characters (|) to highlight the resulting alignment.

Visual Basic
Dim myFName As String = "Fred"
Dim myLName As String = "Opals"
Dim myInt As Integer = 100
Dim FormatFName As String = String.Format("First Name = |{0,10}|", myFName)
Dim FormatLName As String = String.Format("Last Name = |{0,10}|", myLName)
Dim FormatPrice As String = String.Format("Price = |{0,10:C }|", myInt)

FormatFName = String.Format("First Name = |{0,-10}|", myFName)
FormatLName = String.Format("Last Name = |{0,-10}|", myLName)
FormatPrice = String.Format("Price = |{0,-10:C }|", myInt)
string myFName = "Fred";
string myLName = "Opals";
int myInt = 100;
string FormatFName = String.Format("First Name = |{0,10}|", myFName);
string FormatLName = String.Format("Last Name = |{0,10}|", myLName);
string FormatPrice = String.Format("Price = |{0,10:C}|", myInt); 

FormatFName = String.Format("First Name = |{0,-10}|", myFName);
FormatLName = String.Format("Last Name = |{0,-10}|", myLName);
FormatPrice = String.Format("Price = |{0,-10:C}|", myInt);

The preceding code returns the following string values in the U.S. English culture. Different cultures display different currency symbols and separators.

First Name = |          Fred|
Last Name = |         Opals|
Price = |           $100.00|
First Name = |Fred      |
Last Name = |Opals     |
Price = |$100.00   |
Silverlight
复合格式化

.NET Framework 复合格式设置功能使用对象列表和复合格式字符串作为输入。 复合格式字符串由固定文本和索引占位符混和组成,其中索引占位符称为格式项,对应于列表中的对象。 格式设置操作产生的结果字符串由原始固定文本和列表中对象的字符串表示形式混和组成。

复合格式设置功能受 FormatAppendFormat 等方法支持。 String..::.Format 方法可产生设置了格式的结果字符串,AppendFormat 方法可将设置了格式的结果字符串追加到 StringBuilder 对象。

复合格式字符串和对象列表将用作支持复合格式设置功能的方法的参数。 复合格式字符串由零个或多个固定文本段与一个或多个格式项混和组成。 固定文本是所选择的任何字符串,并且每个格式项对应于列表中的一个对象或装箱的结构。 复合格式设置功能返回新的结果字符串,其中每个格式项都被列表中相应对象的字符串表示形式取代。

可考虑使用以下 Format 代码段。

Visual Basic
Dim myName As String = "Fred"
String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now)
string myName = "Fred";
String.Format("Name = {0}, hours = {1:hh}", myName, DateTime.Now);

固定文本为“Name = ”和“, hours = ”。 格式项为“{0}”和“{1:hh}”,前者的索引为 0,对应于对象 myName,后者的索引为 1,对应于对象 DateTime.Now

每个格式项都采用下面的形式并包含以下组件:

{索引[,对齐][:格式字符串]}

必须使用成对的大括号(“{”和“}”)。

索引组件

强制“索引”组件(也叫参数说明符)是一个从 0 开始的数字,可标识对象列表中对应的项。 也就是说,参数说明符为 0 的格式项列表中的第一个对象,参数说明符为 1 的格式项列表中的第二个对象,依次类推。

通过指定相同的参数说明符,多个格式项可以引用对象列表中的同一个元素。 例如,通过指定类似于“{0:X} {0:E} {0:N}”的复合格式字符串,可以将同一个数值设置为十六进制、科学记数法和数字格式。

每个格式项都可以引用列表中的任一对象。 例如,如果有三个对象,则可以通过指定类似于“{1} {0} {2}”的复合格式字符串来设置第二、第一和第三个对象的格式。 格式项未引用的对象会被忽略。 如果参数说明符指定了超出对象列表范围的项,将导致运行时异常。

对齐组件

可选的“对齐”组件是一个带符号的整数,指示首选的设置了格式的字段宽度。 如果“对齐”值小于设置了格式的字符串的长度,“对齐”会被忽略,并且使用设置了格式的字符串的长度作为字段宽度。 如果“对齐”为正数,字段中设置了格式的数据为右对齐;如果“对齐”为负数,字段中的设置了格式的数据为左对齐。 如果需要填充,则使用空白。 如果指定“对齐”,就需要使用逗号。

格式字符串组件

可选的“格式字符串”组件是适合正在设置格式的对象类型的格式字符串。 如果对应的对象是数值,则指定标准数值格式字符串自定义数值格式字符串;如果对应的对象是 DateTimeDateTimeOffset 对象,则指定标准日期和时间格式字符串自定义日期和时间格式字符串;或者,如果对应的对象是枚举值,则指定枚举格式字符串 如果不指定“格式字符串”,则对数字、日期和时间或者枚举类型使用常规(“G”)格式说明符。 如果指定“格式说明符”,需要使用冒号。

转义大括号

左大括号和右大括号被解释为格式项的开始和结束。 因此,必须使用转义序列显示文本左大括号或右大括号。 在固定文本中指定两个左大括号 ("{{") 以显示一个左大括号 ("{"),或指定两个右大括号 ("}}") 以显示一个右大括号 ("}")。 按照在格式项中遇到大括号的顺序依次解释它们。 不支持解释嵌套的大括号。

解释转义大括号的方式会导致意外的结果。 例如,考虑要显示一个左大括号、一个设置为十进制数格式的数值和一个右大括号的格式项“{{{0:D}}}”。 但是,实际是按照以下方式解释该格式项:

  1. 前两个左大括号 ("{{") 被转义,生成一个左大括号。

  2. 之后的三个字符 ("{0:") 被解释为格式项的开始。

  3. 下一个字符 ("D") 将被解释为 Decimal 标准数值格式说明符,但后面的两个转义大括号 ("}}") 生成单个大括号。 由于得到的字符串 ("D}") 不是标准数值格式说明符号,所以得到的字符串会被解释为用于显示字符串“D}”的自定义格式字符串。

  4. 最后一个大括号 ("}") 被解释为格式项的结束。

  5. 显示的最终结果是字符串“{D}”。 不会显示本来要设置格式的数值。

在编写代码时,避免错误解释转义大括号和格式项的一种方法是单独设置大括号和格式项的格式。 也就是说,在第一个格式设置操作中显示文本左大括号,在下一操作中显示格式项的结果,然后在最后一个操作中显示文本右大括号。 下面的示例阐释了这种方法。

Visual Basic
Dim value As Integer = 6324
Dim output As String = String.Format("{0}{1:D}{2}", _
                                     "{", value, "}")
outputBlock.Text += output & vbCrLf
' The example displays the following output:
'       {6324}
int value = 6324;
string output = string.Format("{0}{1:D}{2}",
                             "{", value, "}");
outputBlock.Text += output + "\n";
// The example displays the following output:
//       {6324}                            

处理顺序

通过执行以下列表中的步骤,将参数列表中与格式项对应的每个值转换为一个字符串。 如果符合前三个步骤中的任一条件,则在此步骤中返回值的字符串表示形式,并且不执行后续步骤。

  1. 如果要设置格式的值为 null,则将返回空字符串 ("")。

  2. 如果复合格式设置方法包括也实现 ICustomFormatter 接口的类型 IFormatProvider 的参数,则将该值传递给 ICustomFormatter..::.Format 方法。

  3. 如果该值实现 IFormattable 接口,则调用其 IFormattable..::.ToString 方法。

  4. 调用类型的 ToString 方法(此方法已重写或继承自 Object 类)。

前面的步骤执行完毕之后应用对齐。

下面的示例显示使用复合格式设置创建的一个字符串和使用对象的 ToString 方法创建的另一个字符串。 两种格式设置类型产生相同的结果。

Visual Basic
Dim FormatString1 As String = String.Format("{0:dddd MMMM}", DateTime.Now)
Dim FormatString2 As String = DateTime.Now.ToString("dddd MMMM") 
string FormatString1 = String.Format("{0:dddd MMMM}", DateTime.Now);
string FormatString2 = DateTime.Now.ToString("dddd MMMM");

假定当前日期是五月的某个星期四,则在美国英语区域性中,上述示例中的两个字符串的值都将是 Thursday May 英语区域性。

下面的示例说明为多个对象设置格式,包括用两种不同的方式为一个对象设置格式。

Visual Basic
Dim myName As String = "Fred"
String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
      myName, DateTime.Now)
string myName = "Fred";
String.Format("Name = {0}, hours = {1:hh}, minutes = {1:mm}",
      myName, DateTime.Now);

上述代码返回的字符串值为 "Name = Fred, hours = 07, minutes = 23",其中当前的时间反映了这些数字。

下列示例说明了对齐在格式设置中的使用。 设置了格式的参数放置在竖线字符 (|) 之间以突出显示得到的对齐。

Visual Basic
Dim myFName As String = "Fred"
Dim myLName As String = "Opals"
Dim myInt As Integer = 100
Dim FormatFName As String = String.Format("First Name = |{0,10}|", myFName)
Dim FormatLName As String = String.Format("Last Name = |{0,10}|", myLName)
Dim FormatPrice As String = String.Format("Price = |{0,10:C }|", myInt)

FormatFName = String.Format("First Name = |{0,-10}|", myFName)
FormatLName = String.Format("Last Name = |{0,-10}|", myLName)
FormatPrice = String.Format("Price = |{0,-10:C }|", myInt)
string myFName = "Fred";
string myLName = "Opals";
int myInt = 100;
string FormatFName = String.Format("First Name = |{0,10}|", myFName);
string FormatLName = String.Format("Last Name = |{0,10}|", myLName);
string FormatPrice = String.Format("Price = |{0,10:C}|", myInt); 

FormatFName = String.Format("First Name = |{0,-10}|", myFName);
FormatLName = String.Format("Last Name = |{0,-10}|", myLName);
FormatPrice = String.Format("Price = |{0,-10:C}|", myInt);

在美国,上述代码将返回以下字符串值。 英语区域性。 不同的区域性显示不同的货币符号和分隔符。

First Name = |          Fred|
Last Name = |         Opals|
Price = |           $100.00|
First Name = |Fred      |
Last Name = |Opals     |
Price = |$100.00   |

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多