ここでの他の答えは重要なポイントに当てはまりますが、それらをすべてまとめて、どのようにString.Format
機能するかを調べてみましょう。
5つのオーバーロードがありますが、すべてがリダイレクトされるものについてのみ説明します(これは実際のコードではありません。ReflectorまたはILSpyで表示する場合は、にありますStringBuilder.AppendFormat
)。これは、理解しやすいように簡略化されています。
public static string Format(IFormatProvider provider, string format, params object[] args)
{
StringBuilder sb = new StringBuilder();
// Break up the format string into an array of tokens
Token[] tokens = ParseFormatString(format);
foreach (Token token in tokens)
{
switch (token.TokenType)
{
// A Text token is just some text to output directly
case TokenType.Text:
sb.Append(token.Text);
break;
// An Index token represents something like {0} or {2:format}
// token.Index is the argument index
// token.FormatText is the format string inside ('' in the first example, 'format' in the second example)
case TokenType.Index:
{
object arg = args[token.Index];
IFormattable formattable = arg as IFormattable;
if (formattable != null && token.FormatText.Length > 0)
{
// If the argument is IFormattable we pass it the format string specified with the index
sb.Append(formattable.ToString(token.FormatText, provider));
}
else
{
// Otherwise we just use Object.ToString
sb.Append(arg.ToString());
}
}
break;
}
}
return sb.ToString();
}
あなたの質問では、「05-22-2012」を渡したときにフォーマット文字列が適用されない理由を尋ねます。Guffaが言ったように、それはDateTimeオブジェクトではなく、Stringオブジェクトです。
GSerjoが言ったように、文字列はIFormattableではありません。書式設定は何かを文字列に変換するプロセスであるため、文字列は書式設定できません。文字列はすでに文字列です!
したがって、Formatメソッドがインデクサーにarg
到達すると、IFormattableではなくなり、単に。を呼び出すことがわかりますToString
。文字列に対してToStringを呼び出すと、それ自体が返されます。これはすでに文字列です。
要約すると、フォーマット文字列に内部フォーマット文字列({0:format}など)のインデックスが含まれている場合、その内部フォーマット文字列は、関連付けられた引数がIFormattable
であり、フォーマット文字列の処理方法を認識している場合にのみ適用されます。それを与える。