13

IFormattableの適切なリファレンス実装はありますか? オブジェクトに少なくとも 1 つのカスタムを作成する予定でIFormatProviderあり、 に渡されるさまざまな可能なパラメータ セットに対してワイヤリングが正しいことを確認したいと考えていますIFormattable.ToString(string, IFormatProvider)

私がこれまでに持っているもの:

public class MyDataClass : IFormattable
{
    /// <seealso cref="IFormattable.ToString(string, IFormatProvider)"/>
    public string ToString(string format, IFormatProvider formatProvider)
    {
        ICustomFormatter formatter = (ICustomFormatter)formatProvider.GetFormat(typeof(ICustomFormatter));
        return formatter.Format(format, this, formatProvider);
    }
}

しかし、カバーする必要がある他の潜在的な状況があるようです。

  1. が null の場合formatProvider、フォールバックする必要がありますthis.ToString()か?
  2. formatProvider.GetFormat(typeof(ICustomFormatter))を返す場合null、スローすべき特定の例外はありますか?

ブログの投稿、コード サンプル、MSDN の参照を歓迎します。

4

2 に答える 2

41

.NET Framework のフォーマット インフラストラクチャの設計を誤解しているようです。ICustomFormatterの実装内では絶対に参照しないでください。これIFormattable.ToStringは、そのインターフェイスの意図した目的と衝突するためです。

IFormattable

オブジェクトは、それ自体をフォーマットする方法を知っている場合にのみ実装する必要がありIFormattableます (理想的には、もちろんそれを別のクラスに委譲する必要がありますが、ここでは意図的な結合があります)。オブジェクトは、複数の異なる方法で自分自身をフォーマットする方法を知っている場合があるため、フォーマット文字列を使用してそれらの中から選択できます。それでも、文化によって異なるなど、まだ情報が不足している可能性があります。したがって、このような情報を間接的に提供する 2 番目のパラメーターがあります。

に渡される型は、が提供されIFormatProvider.GetFormatたクラスに固有の型またはインターフェイスであることを意図しています。IFormatProvider

たとえば、組み込みの数値型は のインスタンスを取得できるようにする必要がありますがSystem.Globalization.NumberFormatInfoDateTime関連するクラスは を取得できるようにする必要がありますSystem.Globalization.DateTimeFormatInfo

実装中IFormattable

では、新しい自己書式設定クラスを作成しているとしましょう。自分自身をフォーマットする方法が 1 つしかわかっていない場合は、単にオーバーライドするだけobject.ToString()で、それ以上のことは何もしません。クラスが自分自身をフォーマットする複数の方法を知っている場合は、 を実装する必要がありますIFormattable

formatパラメータ_

(一般的な形式を表す)の形式文字列のドキュメントごとにサポートする必要があります。null または空の書式文字列は、書式文字列の と同等にすることをお勧めします。それ以外の場合、正確な意味は私たち次第です。IFormattable.ToString"G""G"

formatProviderパラメータ_

文化固有の何かが必要な場合、またはそれ以外の場合は異なる場合は、IFormatProviderパラメーターを利用する必要があります。を使用してリクエストするタイプがありますIFormatProvider.GetFormat。が nullの場合IFormatProvider、または必要なIFormatProvider.GetFormat型に対して null を返す場合は、このさまざまな情報についてデフォルトのソースにフォールバックする必要があります。

デフォルトのソースは静的である必要はありません。デフォルトのソースはアプリのユーザー設定である可能性があり、formatProviderオプションの変更をプレビューしたり、シリアル化に固定形式が必要な場合に使用されます。

また、フォーマットに一部のサブオブジェクトのフォーマットが含まれる可能性もあります。その場合、おそらくIFormatProviderダウンを渡したいでしょう。MSDN には、まさにこのケースを示す優れた実装例があります。IFormattable

その他のToStringオーバーロード

実装するときは、次と同等の方法でオーバーライドするIFormattableことが重要ですObject.ToString()

public override string ToString()
{
    return this.ToString(null, System.Globalization.CultureInfo.CurrentCulture);
}

そうすることで、somestring + yourobjectが と同等であることが保証string.Format("{0}{1}",somestring, yourobject)されます。これは、ユーザーが真であると期待するものです。

ユーザーの利便性のために、おそらく提供する必要がありますstring ToString(string format)。また、既定の形式に の恩恵を受けるさまざまなコンポーネントがあるIFormatProvider場合は、 も提供することをお勧めしますpublic string ToString(IFormatProvider provider)

ICustomFormatter

では、それ自体をフォーマットする方法がわからないクラスをフォーマットしたい場合、またはクラス自体でサポートされていないフォーマットを使用したい場合はどうすればよいでしょうか。そこで、ICustomFormatter が重要になります。IFormatProvider型を提供できる は、や などのメソッドでパラメーターICustomFormatterとして渡すことができます。IFormatProviderstring.FormatStringBuilder.AppendFormat

提供されICustomFormatterているには、Formatフォーマットを行うたびに呼び出されるメソッドがstring.Formatあります。ICustomFormatterが使用されているフォーマット文字列に慣れていない場合、またはその型をサポートしていない場合は、単にIFormattable.ToStringorに委譲しObject.ToStringます。このICustomFormatterドキュメントには、フォーマット サポートをまだ提供していないオブジェクトをフォーマットする場合に必要なものと、既存の .xml ファイルに別のフォーマットを追加するだけの場合に必要なもののリストが記載されていますIFormattable。また、追加のフォーマット ケースを追加する例も示します。

参照

この MSDN ページでは、.NET フォーマット システムの優れた概要を提供し、MSDN の他のほとんどすべての関連ページへのリンクを提供します。フォーマット関連のほぼすべての質問を開始するのに最適な場所です。

于 2013-01-10T23:10:06.560 に答える
0

このような質問については、Monoソース コード内に適切な情報源があります。mscorlib.dllコード内で、これがかなりの数使用されている可能性があります。

于 2013-01-08T18:17:19.920 に答える