80

例如,可以以许多不同的方式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())
4

7 回答 7

89

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

可以选择提供格式字符串:

{ index[,alignment][ : formatString] }

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

AnIFormatProvider也可用于捕获基本格式标准/默认值等。此处此处的示例。

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

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

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

  3. 是的,见上文。

于 2012-05-09T08:27:42.170 回答
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())
于 2012-05-09T08:26:09.570 回答
5
  1. 查看官方 MSDN 文档,这里有 DateTime 格式字符串的完整列表:http: //msdn.microsoft.com/en-us/library/az4se3k1.aspx。确实有不少“神奇”的字符串。

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

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

于 2012-05-09T08:28:21.237 回答
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)。提供者通常会告诉您系统的文化是什么。通常为空,因为人们没有像您在案例中那样传递它 String.Format() 。

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

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

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

    本质上,如果您希望自己的对象使用您实现的格式执行某些操作IFormattable

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

于 2012-05-09T08:32:22.577 回答
0

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

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

于 2012-05-09T08:24:42.383 回答
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()并得到你指定的输出。

于 2012-05-09T08:26:22.323 回答
0

并回答您的第三个问题:使用这种语法是不可能的,但是您可以为您没有创建的类型提供实例,或者在您的类型中实现IFormatProvider(尽管基本上是 extends )。ICustomFormatterIFormattableToString

于 2012-05-09T08:29:45.110 回答