【问题标题】:String.Format - how it works and how to implement custom formatstringsString.Format - 它是如何工作的以及如何实现自定义格式字符串
【发布时间】:2012-05-09 08:20:07
【问题描述】:

使用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())

【问题讨论】:

标签: c# .net vb.net string string-formatting


【解决方案1】:

String.Format 将字符串中的每个标记({0} 等)与相应的对象匹配:https://docs.microsoft.com/en-us/dotnet/api/system.string.format#overloads

可选提供格式字符串:

{ index[,alignment][ : formatString] }

如果提供了formatString,则相应的对象必须实现IFormattable,特别是接受formatString并返回相应格式字符串的ToString方法:https://docs.microsoft.com/en-us/dotnet/api/system.iformattable.tostring

IFormatProvider 也可用于捕获基本格式标准/默认值等。例如 herehere

所以按顺序回答你的问题:

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

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

  3. 是的,见上文。

【讨论】:

  • +1 用于链接到文档。 “在互联网上搜索”可以。但是当您需要更深入的了解时,您应该阅读手册。
  • 不错的答案,但你能告诉我在哪里可以找到每个实现IFormattable 的类,我可以在哪里找到允许的格式字符串。例如 DateTime 支持(在我的头上)y M d h m s 等等。数字类型支持来自货币的C,但这并不是我通过搜索arround而不是查看Microsoft文档所知道的全部。
  • @hwcverwe Formatting Types
【解决方案2】:

据我了解,您需要在您的班级中实现 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())

【讨论】:

    【解决方案3】:
    1. 查看官方 MSDN 文档,此处有 DateTime 格式字符串的完整列表:http://msdn.microsoft.com/en-us/library/az4se3k1.aspx。确实有不少“神奇”的字符串。

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

    3. 是的,您可以自己编写,如果您有可以以不同方式格式化的数据,您可能应该通过实现 IFormattable 编写自定义格式化程序,再次查看此处的文档:http://msdn.microsoft.com/en-us/library/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(string format, IFormatProvider provider)。提供者通常会告诉您系统的文化是什么。通常为 null,因为人们没有像您在案例中那样传递 String.Format()。

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

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

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

        基本上,如果您希望自己的对象使用您实现IFormattable 提供的格式来做某事。

      有大量的支持类和枚举器来确保格式字符串在很大程度上相似。 More here.

      【讨论】:

        【解决方案5】:

        日期的文档可以在这里找到: 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() 那样做,得到你指定的输出。

        【讨论】:

          【解决方案6】:

          并回答您的第三个问题:使用这种语法是不可能的,但是您可以为您未创建的类型提供 IFormatProviderICustomFormatter 的实例,或者在您的类型中实现 IFormattable(尽管,这基本上扩展了ToString)。

          【讨论】:

            【解决方案7】:

            是的,这是可能的——它可以完全定制。查看this 的日期和时间自定义格式。

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

            【讨论】:

            • -1 - OP 询问的不仅仅是DateTime 格式。只是一个链接不是答案。
            • 非常苛刻。 DateTime 是其中一个方面,当您投反对票时,我正在扩展我的答案。
            • 展开答案然后发布,您不会被否决。
            猜你喜欢
            • 2015-09-05
            • 1970-01-01
            • 1970-01-01
            • 2019-12-25
            • 1970-01-01
            • 1970-01-01
            • 2013-06-04
            • 1970-01-01
            • 2019-01-08
            相关资源
            最近更新 更多