String.Format-它如何工作以及如何实现自定义格式字符串


79

有了String.Format()它,可以例如格式化DateTime对象在许多不同的方式。每次寻找所需格式时,都需要在Internet上进行搜索。我几乎总是找到可以使用的示例。例如:

String.Format("{0:MM/dd/yyyy}", DateTime.Now);          // "09/05/2012"

但是我不知道它如何工作以及哪些类支持这些“魔术”附加字符串。

所以我的问题是:

  1. 如何String.Format将附加信息映射MM/dd/yyyy到字符串结果?
  2. 所有Microsoft对象都支持此功能吗?
    这是否记录在某处?
  3. 是否可以做这样的事情:
    String.Format("{0:MyCustomFormat}", new MyOwnClass())

Answers:


88

String.Format将字符串({0}等)内的每个标记与相应的对象进行匹配:http : //msdn.microsoft.com/en-us/library/system.string.format.aspx

可选提供格式字符串:

{ index[,alignment][ : formatString] }

如果formatString提供,则相应的对象必须实现IFormattable,尤其是实现并ToString接收formatString相应的格式化字符串的方法:http : //msdn.microsoft.com/zh-cn/library/system.iformattable.tostring.aspx

一个IFormatProvider也可以使用能够用于捕获基本格式标准/默认值等。实施例在这里在这里

因此,按顺序回答您的问题:

  1. 它在对象上使用IFormattable接口的ToString()方法,DateTime并传递该MM/dd/yyyy格式字符串。该实现返回正确的字符串。

  2. 实现的任何对象都IFormattable支持此功能。您甚至可以编写自己的!

  3. 是的,请参见上文。


11
+1用于链接到文档。可以在互联网上搜索。但是,当您需要更深入的了解时,应该阅读《手册》。
MarkJ

好的答案,但是您能告诉我在哪里可以找到实现的每个类IFormattable,在哪里可以找到允许的formatStrings。例如,DateTime支持(在我的头上)y M d h m s等等。数值类型C从货币中获得支持,但我从搜索周围而不是通过查看Microsoft文档就不知道这些。
hwcverwe 2012年

@hwcverwe-几乎所有Google搜索都将MSDN文档放在任何对象搜索的顶部或顶部。没有一个页面可以显示每个对象的ToString(...)-可能有“无限”的数量,因为默认情况下,所有对象都至少实现ToString(),尽管不一定要实现ToString(format)。
桑科旺科(Wonko the Sane),2012年


20

据我了解,您将需要在您的类中实现IFormattable来支持这一点。然后有方法ToString,它采用传递给String.Format的参数。

这是一个例子。

// Define other methods and classes here
public class Sample : IFormattable
{
     public string ToString(string format, IFormatProvider provider)
     {
         return String.Concat("Your custom format was ", format);
     }
}

String.Format("{0:MyCustomFormat}", new Sample())

5
  1. 请查看MSDN官方文档,这里有DateTime格式字符串的完整列表:http : //msdn.microsoft.com/zh-cn/library/az4se3k1.aspx。确实有很多“魔术”字符串。

  2. 据我所知,并非所有类型都具有“有趣的”格式,但是所有类型都支持ToString()。如果您需要格式化内置对象,则可以添加扩展方法来执行此操作,但是通常在需要它的任何地方都提供格式化(或者换种说法,我只为自己的类型编写了自定义格式化程序) 。

  3. 是的,您可以编写自己的数据,如果您拥有可以以不同方式格式化的数据,则可能应该通过实现IFormattable来编写自定义格式化程序,再次在此处查看文档:http : //msdn.microsoft.com/zh-cn/库/ system.iformattable.aspx。这很简单,您只需检查提供的字符串并根据这些字符串写出数据,幕后就不会产生魔法:-)


4

在String.Format的幕后工作如下:

IFormattable formattable = objectToFormat as IFormattable;
if (formattable != null)
{
    formattable.ToString(objectToFormat);
}
else
{
    objectToFormat.ToString();
}

对于您的问题,

  1. String.Format如何将附加信息MM / dd / yyyy映射到字符串结果?

    如上所述,它仅调用IFormattable .ToString(字符串格式,IFormatProvider提供程序)。提供程序通常可以告诉您系统的文化。通常为null,因为人们没有像在您的案例中那样传递String.Format()。

  2. 是否所有Microsoft对象都支持此功能?这是在某处记录的吗?

    任何实现IFormattable的东西都可以。

  3. 是否可以做这样的事情: String.Format("{0:MyCustomFormat}, new MyOwnClass())

    本质上,如果您希望自己的对象以实现的格式进行操作IFormattable

有大量支持类和枚举器,以确保格式字符串在很大程度上相似。 这里更多


0

是的,有可能-可以完全自定义。在日期和时间自定义格式上查看文档链接。

如果您有自己的对象,则由您自己来覆盖ToString()方法并输出您认为合适的表示形式。一旦执行此操作,就可以使用,String.Format("{0:MyCustomFormat}", new MyOwnClass())因为这隐式调用MyOwnClass.ToString()


-1-OP要求的不仅仅是DateTime格式化。只是链接不是答案。
奥德

1
非常苛刻。DateTime是方面之一,当您投票否决时,我正在扩大答案。
Maciej

6
扩大答案,然后发布,您将不会感到沮丧。
奥德(Oded)

0

日期的文档可以在这里找到:http : //msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

那应该可以告诉您MM之类的所有日期格式字符的确切含义。

如果要更改自定义类的字符串输出方式,则可以重写ToString方法,如下所示:

public class User
{
     public string Name { get; set; }
     public int Age { get; set; }

     public override string ToString()
     {
         return this.Name + " is " + this.Age + " years old.";
     }
}

然后您可以执行类似的操作myUser.ToString()并获取您指定的输出。


0

并回答你的第三个问题:这是不可能的,这种语法,但您可以提供的实例IFormatProviderICustomFormatter一个类型,你没有创建,或者实现IFormattable你的类型中(虽然,基本上延伸ToString)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.