web-dev-qa-db-ja.com

String.Format-仕組みとカスタム形式文字列の実装方法

String.Format()を使用すると、たとえばDateTimeオブジェクトをさまざまな方法でフォーマットできます。目的の形式を探すたびに、インターネットで検索する必要があります。ほとんどの場合、使用できる例を見つけます。例えば:

_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())
77
hwcverwe

_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/en-us/library/system.iformattable.tostring.aspx

IFormatProviderも使用できます。これは、基本的なフォーマット標準/デフォルトなどをキャプチャするために使用できます。例 here および here

順番にあなたの質問への答え:

  1. IFormattableオブジェクトでDateTimeインターフェイスのToString()メソッドを使用し、_MM/dd/yyyy_形式文字列を渡します。正しい文字列を返すのはその実装です。

  2. IFormattableを実装するオブジェクトはすべて、この機能をサポートしています。あなたも自分で書くことができます!

  3. はい、上記を参照してください。

84
yamen

私の理解では、これをサポートするには、クラスにIFormattableを実装する必要があります。これには、String.Formatに渡すパラメーターを受け取るToStringメソッドがあります。

以下に例を示します。

// 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())
18
Dean Thomas
  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
Steve Haigh

カバーの下で、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 を実装した提供フォーマットで何かをさせたい場合。

書式文字列が大きく同様であることを保証するために、膨大な数のサポートクラスと列挙子があります。 詳細はこちら

3
M Afifi

はい、可能です-完全にカスタマイズできます。 this 日付と時刻のカスタムフォーマットに関するドキュメントリンクをご覧ください。

独自のオブジェクトがある場合、ToString()メソッドをオーバーライドして、適切な表現と思われるものを出力するのはユーザー次第です。これを行うと、String.Format("{0:MyCustomFormat}", new MyOwnClass())を暗黙的に呼び出すため、MyOwnClass.ToString()を使用できます。

0
Maciej

日付のドキュメントは次の場所にあります。 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()のようなことをして、指定した出力を得ることができます。

3番目の質問に答えるために:この構文では不可能ですが、作成していない型にIFormatProviderICustomFormatterのインスタンスを提供したり、IFormattableを実装したりできます。あなたの型の中(ただし、それは基本的にToStringを拡張します)。

0
phg