导出 (0) 打印
全部展开
此文章由机器翻译。 将光标移到文章的句子上,以查看原文。 更多信息。
译文
原文

String.Format 方法

将指定字符串中的每个格式项替换为相应对象的值的文本等效项。

重载此成员。有关此成员的完整信息(包括语法、用法和示例),请单击重载列表中的相应名称。

  名称 说明
公共方法 静态成员 Format(String, Object) 将指定字符串中的一个或多个格式项替换为指定对象的字符串表示形式。
公共方法 静态成员 Format(String, Object[]) 将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。
公共方法 静态成员 Format(IFormatProvider, String, Object[]) 将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。 参数提供区域性特定的格式设置信息。
公共方法 静态成员 Format(String, Object, Object) 将指定字符串中的格式项替换为两个指定对象的字符串表示形式。
公共方法 静态成员 Format(String, Object, Object, Object) 将指定字符串中的格式项替换为三个指定对象的字符串表示形式。
页首

本节内容:

重载方法语法
参数
返回值
异常
调用哪个方法?
简单的格式方法
格式项 。
参数如何格式化。
格式项具有相同索引
格式化和区域性
自定义格式化操作
示例:
       格式化单个参数
       格式化两个参数。
       格式化三个参数
       格式化三个以上参数
       区分区域性的格式化
       自定义格式化操作
       截获提供程序和罗马体数字格式化程序
版本信息

重载方法语法

有关选择重载函数的其他指南,请参阅 调用哪个方法?

String String.Format(String format , Object arg0 )

使用指定的对象的字符串表示替换格式项 (示例) 。

String String.Format(String format , Object arg0 , Object arg1 )

使用两个指定的对象的字符串表示方法替换格式项 (示例) 。

String String.Format(String format , Object arg0 , Object arg1 , Object arg2 )

将格式项替换为三个指定对象的字符串表示形式(示例)。

String String.Format(String format , params Object[] args )

将格式项替换为指定数组中相应对象的字符串表示形式(example)。

String String.Format(IFormatProvider provider , String format , params Object[] args )

用对应的对象的字符串表示方法替换格式项,并使用指定的特定区域性的格式化信息 (示例) 或自定义格式化信息 (示例)。

参数

这是Format 方法完整的参数列表;参见上面的使用重载的参数的重载语法。 format 参数被所有重载函数使用。

参数

类型

说明

s

String

包含一个或多个格式项的复合格式字符串 (请参见 格式项)。

arg0

String

格式化第一个或唯一的对象。

arg1

String

要设置格式的第二个对象。

arg2

String

要设置格式的第三个对象。

args

String []

格式化零个或多个对象时,提供以逗号分隔的列表或以数组出现。

provider

IFormatProvider

提供自定义或区域性特定的格式化信息的对象。

返回值

类型:String
format 的一个副本,其中格式项已替换为相应参数的字符串表示形式。

异常

例外

条件

已引发

ArgumentNullException

formatnull

所有超加载。

FormatException

format 无效。

- 或 -

格式项的索引小于 0(零)或大于等于参数列表中参数的数目。

所有超加载。

调用哪个方法?

目标

Call

使用当前区域性的约定,格式化一个或多个对象。

除包含一个 provider 参数的重载函数外,所有 Format 重载函数包含一个或多个对象参数的String 参数。 因此,不必确定要调用Format 哪一个重载函数。 根据参数列表,语言编译器将在一个没有 provider 参数的重载函数中选择适当的重载函数。 例如,如果参数列表有五个变量,编译器将调用 Format(String, Object[]) 方法。

使用特定区域性的约定,格式化一个或多个对象。

Format(IFormatProvider, String, Object[])

执行自定义格式化操作与 ICustomFormatter 实现或 IFormattable 实现。

Format(IFormatProvider, String, Object[])

简单的格式方法

每个重载的 Format 方法使用 复合格式设置功能,包括从零开始的索引的占位符称为格式项,复合格式字符串中。 每个格式项都由参数数组中相应参数的字符串表示形式替换。 如果参数的值是 null,格式项将被String.Empty替换。 例如,以下调用到 Format(String, Object, Object, Object) 方法包括一个格式字符串,与三个格式项、{0},{1},{2} 和三个项目的参数列表。


DateTime dat = new DateTime(2012, 1, 17, 9, 30, 0); 
string city = "Chicago";
int temp = -16;
string output = String.Format("At {0} in {1}, the temperature was {2} degrees.",
                              dat, city, temp);
Console.WriteLine(output);
// The example displays the following output:
//    At 1/17/2012 9:30:00 AM in Chicago, the temperature was -16 degrees.   


格式项 。

格式项具有此语法:

{ index[,alignment][ :formatString] }

中括号表示的是可选元素。 需要左大括号和右大括号。(在格式字符串中包含一个文本左大括号或右大括号,请参见在 复合格式 文章中“省略括号”一节。)

例如,格式化货币值的格式项可能显示如下:


String.Format("{0,-10:C}", 126347.89m);         


格式项具有以下元素:

索引

从零开始的索引的参数的字符串表示形式是要包括在此字符串中的位置。 如果此参数是 null,一个空字符串将包括在该字符串的此位置。

对齐方式

可选。 有符号的整数,指示总长度字段的插入参数和是右对齐(正整数)还是左对齐(负整数)。 如果省略 对齐,对应的参数的字符串表示形式将没有前导或尾随空格地插入到字段中。

formatString

可选。 指定一个对应参数的结果字符串的格式的字符串。 如果省略 formatString,则调用对应的参数的无参数 ToString 方法产生其字符串表示。 如果指定 formatString,格式项引用的参数必须实现 IFormattable 接口。 支持格式字符串的类型包括:

但是,请注意任何自定义类型可以实现 IFormattable 或扩展现有类型的 IFormattable 实现。

下面的示例使用 alignmentformatString 参数产生格式化输出。


using System;

public class Example
{
   public static void Main()
   {
      // Create array of 5-tuples with population data for three U.S. cities, 1940-1950.
      Tuple<string, DateTime, int, DateTime, int>[] cities = 
          { Tuple.Create("Los Angeles", new DateTime(1940, 1, 1), 1504277, 
                         new DateTime(1950, 1, 1), 1970358),
            Tuple.Create("New York", new DateTime(1940, 1, 1), 7454995, 
                         new DateTime(1950, 1, 1), 7891957),  
            Tuple.Create("Chicago", new DateTime(1940, 1, 1), 3396808, 
                         new DateTime(1950, 1, 1), 3620962),  
            Tuple.Create("Detroit", new DateTime(1940, 1, 1), 1623452, 
                         new DateTime(1950, 1, 1), 1849568) };

      // Display header
      string header = String.Format("{0,-12}{1,8}{2,12}{1,8}{2,12}{3,14}\n",
                                    "City", "Year", "Population", "Change (%)");
      Console.WriteLine(header);
      string output;      
      foreach (var city in cities) {
         output = String.Format("{0,-12}{1,8:yyyy}{2,12:N0}{3,8:yyyy}{4,12:N0}{5,14:P1}",
                                city.Item1, city.Item2, city.Item3, city.Item4, city.Item5,
                                (city.Item5 - city.Item3)/ (double)city.Item3);
         Console.WriteLine(output);
      }
   }
}
// The example displays the following output:
//    City            Year  Population    Year  Population    Change (%)
//    
//    Los Angeles     1940   1,504,277    1950   1,970,358        31.0 %
//    New York        1940   7,454,995    1950   7,891,957         5.9 %
//    Chicago         1940   3,396,808    1950   3,620,962         6.6 %
//    Detroit         1940   1,623,452    1950   1,849,568        13.9 %


参数如何格式化。

从最初该字符串开始按顺序处理格式项。 每个格式项都有对应于方法的对象参数列表的索引。 Format 方法检索参数并派生其字符串表示方法,如下:

对于截获调用 ICustomFormatter.Format 方法并允许您查看Format 方法所传递给每个复合格式字符串的格式项的格式化方法的信息,请参见 示例 7:截获提供程序和罗马体数字格式化程序

格式项具有相同索引

如果索引项的索引大于或等于参数列表中参数的数目,Format 方法抛出FormatException 异常。 但是,format可以包含比参数更多的格式项,只要多个格式项具有相同索引。 在对 Format(String, Object) 方法的调用在下面的示例中,参数列表具有单个参数,但是,格式字符串由两个格式项:一个显示数字的十进制值,一个显示其十六进制值。


public class Example
{
   public static void Main()
   {
      short[] values= { Int16.MinValue, -27, 0, 1042, Int16.MaxValue };
      Console.WriteLine("{0,10}  {1,10}\n", "Decimal", "Hex");
      foreach (short value in values)
      {
         string formatString = String.Format("{0,10:G}: {0,10:X}", value);
         Console.WriteLine(formatString);
      }   
   }
}
// The example displays the following output:
//       Decimal         Hex
//    
//        -32768:       8000
//           -27:       FFE5
//             0:          0
//          1042:        412
//         32767:       7FFF


格式化和区域性

通常,使用当前区域性的约定,参数列表中的对象被转换为其字符串表示形式,由CultureInfo.CurrentCulture 属性返回。 通过调用 Format(IFormatProvider, String, Object[]) 重载函数控制此行为。 此重载函数的 provider 参数是提供自定义,特定区域性的格式化信息的 IFormatProvider 实现(用于调整格式化过程)。

IFormatProvider 接口具有一个成员,GetFormat,负责返回提供格式化信息的对象。 .NET Framework 具有特定区域性格式化的三个IFormatProvider 实现:

自定义格式化操作

还可以调用 Format(IFormatProvider, String, Object[])重载函数执行自定义格式化操作。 例如,可以设置整数作为标识号或作为电话号码。 若要执行自定义格式化,provider 参数必须实现 IFormatProviderICustomFormatter 接口。 Format(IFormatProvider, String, Object[]) 方法将ICustomFormatter 实现当作provider 参数传递时,Format 方法调用其 IFormatProvider.GetFormat 实现,并请求类型为 ICustomFormatter的对象。 然后调用返回的 ICustomFormatter 对象的 Format 方法设置该复合字符串的每个格式项。

有关提供自定义格式化解决方案的更多信息,请参见 如何:定义和使用自定义数值格式提供程序ICustomFormatter 有关将整数转换为格式的自定义数目的示例,请参见 示例 6:自定义格式化操作 有关将无符号字节数组转换为罗马数字的示例,请参见 示例 7:截获提供程序和罗马体数字格式化程序

示例 1:格式化单个参数

下面的示例使用 Format(String, Object) 方法将一个人的年龄嵌入字符串的中部。


using System;

[assembly: CLSCompliant(true)]
public class Example
{
   public static void Main()
   {
      DateTime birthdate = new DateTime(1993, 7, 28);
      DateTime[] dates = { new DateTime(1993, 8, 16), 
                           new DateTime(1994, 7, 28), 
                           new DateTime(2000, 10, 16), 
                           new DateTime(2003, 7, 27), 
                           new DateTime(2007, 5, 27) };

      foreach (DateTime dateValue in dates)
      {
         TimeSpan interval = dateValue - birthdate;
         // Get the approximate number of years, without accounting for leap years.
         int years = ((int) interval.TotalDays) / 365;
         // See if adding the number of years exceeds dateValue.
         string output;
         if (birthdate.AddYears(years) <= dateValue) {
            output = String.Format("You are now {0} years old.", years);
            Console.WriteLine(output);
         }   
         else {
            output = String.Format("You are now {0} years old.", years - 1);
            Console.WriteLine(output);
         }      
      }
   }
}
// The example displays the following output:
//       You are now 0 years old.
//       You are now 1 years old.
//       You are now 7 years old.
//       You are now 9 years old.
//       You are now 13 years old.


示例 2:格式化两个参数

该示例使用 Format(String, Object, Object) 方法显示泛型Dictionary<TKey, TValue> 对象中存储的时间和温度数据。 注意,格式字符串有三个格式项,而要格式化的对象只有两个。 这是因为, 两个格式项使用列表中(日期和时间值)的第一个对象:第一个格式项显示时间,第二个显示该日期。


using System;
using System.Collections.Generic;

public class Example
{
   public static void Main()
   {
      Dictionary<DateTime, Double> temperatureInfo = new Dictionary<DateTime, Double>(); 
      temperatureInfo.Add(new DateTime(2010, 6, 1, 14, 0, 0), 87.46);
      temperatureInfo.Add(new DateTime(2010, 12, 1, 10, 0, 0), 36.81);

      Console.WriteLine("Temperature Information:\n");
      string output;   
      foreach (var item in temperatureInfo)
      {
         output = String.Format("Temperature at {0,8:t} on {0,9:d}: {1,5:N1}°F", 
                                item.Key, item.Value);
         Console.WriteLine(output);
      }
   }
}
// The example displays the following output:
//       Temperature Information:
//       
//       Temperature at  2:00 PM on  6/1/2010:  87.5°F
//       Temperature at 10:00 AM on 12/1/2010:  36.8°F


示例 3:格式化三个参数

该示例使用 Format(String, Object, Object, Object) 方法创建一个字符串,它说明了使用两个整数值的布尔 And 运算的结果。 请注意,格式字符串包括六个格式项,但该方法在它的参数列表中只有三个项,因为每个项目可以按两种不同方式格式化。


using System;

public class Example
{
   public static void Main()
   {
      string formatString = "    {0,10} ({0,8:X8})\n" + 
                            "And {1,10} ({1,8:X8})\n" + 
                            "  = {2,10} ({2,8:X8})";
      int value1 = 16932;
      int value2 = 15421;
      string result = String.Format(formatString, 
                                    value1, value2, value1 & value2);
      Console.WriteLine(result);
   }
}
// The example displays the following output:
//                16932 (00004224)
//       And      15421 (00003C3D)
//         =         36 (00000024)


示例 4:格式化三个以上参数

该示例创建一个字符串,包含有关特定日期高温和低温的数据。 复合格式字符串在 C# 示例中有 5 个格式项,在 Visual Basic 示例中有 6 个格式项。 两个格式项定义其相应值的字符串表示形式的宽度,第一个格式项还包括标准日期和时间格式字符串。


using System;

public class Example
{
   public static void Main()
   {
      DateTime date1 = new DateTime(2009, 7, 1);
      TimeSpan hiTime = new TimeSpan(14, 17, 32);
      decimal hiTemp = 62.1m; 
      TimeSpan loTime = new TimeSpan(3, 16, 10);
      decimal loTemp = 54.8m; 

      string result1 = String.Format("Temperature on {0:d}:\n{1,11}: {2} degrees (hi)\n{3,11}: {4} degrees (lo)", 
                                     date1, hiTime, hiTemp, loTime, loTemp);
      Console.WriteLine(result1);
      Console.WriteLine();

      string result2 = String.Format("Temperature on {0:d}:\n{1,11}: {2} degrees (hi)\n{3,11}: {4} degrees (lo)", 
                                     new object[] { date1, hiTime, hiTemp, loTime, loTemp });
      Console.WriteLine(result2);
   }
}
// The example displays the following output:
//       Temperature on 7/1/2009:
//          14:17:32: 62.1 degrees (hi)
//          03:16:10: 54.8 degrees (lo)
//       Temperature on 7/1/2009:
//          14:17:32: 62.1 degrees (hi)
//          03:16:10: 54.8 degrees (lo)


还可以以数组形式传递要格式化的对象而不是以参数列表形式。


using System;

public class CityInfo
{
   public CityInfo(String name, int population, Decimal area, int year)
   {
      this.Name = name;
      this.Population = population;
      this.Area = area;
      this.Year = year;
   }

   public readonly String Name; 
   public readonly int Population;
   public readonly Decimal Area;
   public readonly int Year;
}

public class Example
{
   public static void Main()
   {
      CityInfo nyc2010 = new CityInfo("New York", 8175133, 302.64m, 2010);
      ShowPopulationData(nyc2010);
      CityInfo sea2010 = new CityInfo("Seattle", 608660, 83.94m, 2010);      
      ShowPopulationData(sea2010); 
   }

   private static void ShowPopulationData(CityInfo city)
   {
      object[] args = { city.Name, city.Year, city.Population, city.Area };
      String result = String.Format("{0} in {1}: Population {2:N0}, Area {3:N1} sq. feet", 
                                    args);
      Console.WriteLine(result); 
   }
}
// The example displays the following output:
//       New York in 2010: Population 8,175,133, Area 302.6 sq. feet
//       Seattle in 2010: Population 608,660, Area 83.9 sq. feet


示例 5:区分区域性的格式化

该示例使用 Format(IFormatProvider, String, Object[]) 方法显示使用几种不同区域性的一些日期和时间值以及数值的字符串表示形式。


using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      string[] cultureNames = { "en-US", "fr-FR", "de-DE", "es-ES" };

      DateTime dateToDisplay = new DateTime(2009, 9, 1, 18, 32, 0);
      double value = 9164.32;

      Console.WriteLine("Culture     Date                                Value\n");
      foreach (string cultureName in cultureNames)
      {
         CultureInfo culture = new CultureInfo(cultureName);
         string output = String.Format(culture, "{0,-11} {1,-35:D} {2:N}", 
                                       culture.Name, dateToDisplay, value);
         Console.WriteLine(output);
      }    
   }
}
// The example displays the following output:
//    Culture     Date                                Value
//    
//    en-US       Tuesday, September 01, 2009         9,164.32
//    fr-FR       mardi 1 septembre 2009              9 164,32
//    de-DE       Dienstag, 1. September 2009         9.164,32
//    es-ES       martes, 01 de septiembre de 2009    9.164,32


示例 6:自定义格式化操作

该示例定义了格式提供程序以x-xxxxx-xx形式来将整数值格式化为客户账户数目。


using System;

public class TestFormatter
{
   public static void Main()
   {
      int acctNumber = 79203159;
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0}", acctNumber));
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0:G}", acctNumber));
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0:S}", acctNumber));
      Console.WriteLine(String.Format(new CustomerFormatter(), "{0:P}", acctNumber));
      try {
         Console.WriteLine(String.Format(new CustomerFormatter(), "{0:X}", acctNumber));
      }
      catch (FormatException e) {
         Console.WriteLine(e.Message);
      }
   }
}

public class CustomerFormatter : IFormatProvider, ICustomFormatter
{
   public object GetFormat(Type formatType) 
   {
      if (formatType == typeof(ICustomFormatter))        
         return this; 
      else
         return null;
   }

   public string Format(string format, 
	                     object arg, 
	                     IFormatProvider formatProvider) 
   {                       
      if (! this.Equals(formatProvider))
      {
         return null;
      }
      else
      {
         if (String.IsNullOrEmpty(format)) 
            format = "G";

         string customerString = arg.ToString();
         if (customerString.Length < 8)
            customerString = customerString.PadLeft(8, '0');

         format = format.ToUpper();
         switch (format)
         {
            case "G":
               return customerString.Substring(0, 1) + "-" +
                                     customerString.Substring(1, 5) + "-" +
                                     customerString.Substring(6);
            case "S":                          
               return customerString.Substring(0, 1) + "/" +
                                     customerString.Substring(1, 5) + "/" +
                                     customerString.Substring(6);
            case "P":                          
               return customerString.Substring(0, 1) + "." +
                                     customerString.Substring(1, 5) + "." +
                                     customerString.Substring(6);
            default:
               throw new FormatException( 
                         String.Format("The '{0}' format specifier is not supported.", format));
         }
      }   
   }
}
// The example displays the following output:
//       7-92031-59
//       7-92031-59
//       7/92031/59
//       7.92031.59
//       The 'X' format specifier is not supported.


示例 7:截获提供程序和罗马体数字格式化程序

此示例定义实现 ICustomFormatterIFormatProvider 接口的自定义格式提供程序执行以下两项操作:

  • 它显示传递给其 ICustomFormatter.Format 实现的参数。 这使我们查看Format(IFormatProvider, String, Object[]) 方法将哪些参数传递给它尝试格式化的每个对象的自定义格式化实现。 在调试应用程序时,这会很有用。

  • 如果要格式化的对象是通过使用“R”标准格式字符串的无符号字节值,则自定义格式化程序将数字值设置为罗马数字。


using System;
using System.Globalization;

public class InterceptProvider : IFormatProvider, ICustomFormatter
{
   public object GetFormat(Type formatType)
   {
      if (formatType == typeof(ICustomFormatter))
         return this;
      else
         return null;
   }

   public string Format(String format, Object obj, IFormatProvider provider) 
   {
      // Display information about method call.
      string formatString = format ?? "<null>";
      Console.WriteLine("Provider: {0}, Object: {1}, Format String: {2}",
                        provider, obj ?? "<null>", formatString);

      if (obj == null) return String.Empty;

      // If this is a byte and the "R" format string, format it with Roman numerals.
      if (obj is Byte && formatString.ToUpper().Equals("R")) {
         Byte value = (Byte) obj;
         int remainder;
         int result;
         String returnString = String.Empty;

         // Get the hundreds digit(s)
         result = Math.DivRem(value, 100, out remainder);
         if (result > 0)  
            returnString = new String('C', result);
         value = (Byte) remainder;
         // Get the 50s digit
         result = Math.DivRem(value, 50, out remainder);
         if (result == 1)
            returnString += "L";
         value = (Byte) remainder;
         // Get the tens digit.
         result = Math.DivRem(value, 10, out remainder);
         if (result > 0)
            returnString += new String('X', result);
         value = (Byte) remainder; 
         // Get the fives digit.
         result = Math.DivRem(value, 5, out remainder);
         if (result > 0)
            returnString += "V";
         value = (Byte) remainder;
         // Add the ones digit.
         if (remainder > 0) 
            returnString += new String('I', remainder);

         // Check whether we have too many X characters.
         int pos = returnString.IndexOf("XXXX");
         if (pos >= 0) {
            int xPos = returnString.IndexOf("L"); 
            if (xPos >= 0 & xPos == pos - 1)
               returnString = returnString.Replace("LXXXX", "XC");
            else
               returnString = returnString.Replace("XXXX", "XL");   
         }
         // Check whether we have too many I characters
         pos = returnString.IndexOf("IIII");
         if (pos >= 0)
            if (returnString.IndexOf("V") >= 0)
               returnString = returnString.Replace("VIIII", "IX");
            else
               returnString = returnString.Replace("IIII", "IV");    

         return returnString; 
      }   

      // Use default for all other formatting.
      if (obj is IFormattable)
         return ((IFormattable) obj).ToString(format, CultureInfo.CurrentCulture);
      else
         return obj.ToString();
   }
}

public class Example
{
   public static void Main()
   {
      int n = 10;
      double value = 16.935;
      DateTime day = DateTime.Now;
      InterceptProvider provider = new InterceptProvider();
      Console.WriteLine(String.Format(provider, "{0:N0}: {1:C2} on {2:d}\n", n, value, day));
      Console.WriteLine(String.Format(provider, "{0}: {1:F}\n", "Today: ", 
                                      (DayOfWeek) DateTime.Now.DayOfWeek));
      Console.WriteLine(String.Format(provider, "{0:X}, {1}, {2}\n", 
                                      (Byte) 2, (Byte) 12, (Byte) 199));
      Console.WriteLine(String.Format(provider, "{0:R}, {1:R}, {2:R}\n", 
                                      (Byte) 2, (Byte) 12, (Byte) 199));
   }
}
// The example displays the following output:
//    Provider: InterceptProvider, Object: 10, Format String: N0
//    Provider: InterceptProvider, Object: 16.935, Format String: C2
//    Provider: InterceptProvider, Object: 1/31/2013 6:10:28 PM, Format String: d
//    10: $16.94 on 1/31/2013
//    
//    Provider: InterceptProvider, Object: Today: , Format String: <null>
//    Provider: InterceptProvider, Object: Thursday, Format String: F
//    Today: : Thursday
//    
//    Provider: InterceptProvider, Object: 2, Format String: X
//    Provider: InterceptProvider, Object: 12, Format String: <null>
//    Provider: InterceptProvider, Object: 199, Format String: <null>
//    2, 12, 199
//    
//    Provider: InterceptProvider, Object: 2, Format String: R
//    Provider: InterceptProvider, Object: 12, Format String: R
//    Provider: InterceptProvider, Object: 199, Format String: R
//    II, XII, CXCIX


版本信息

.NET Framework

所有超加载在4.5,4,3.5,3.0,2.0,1.1,1.0中均支持

.NET Framework Client Profile

所有超加载在4, 3.5 SP1中均支持

可移植类库

只支持Format(String, Object[])Format(IFormatProvider, String, Object[])

适用于 Windows 商店应用程序的 .NET

Windows 8 仅支持Format(String, Object[])Format(IFormatProvider, String, Object[])

社区附加资源

添加
显示:
© 2014 Microsoft