出力ファイルで使用するためにオブジェクトをカスタム文字列形式にシリアル化するためのベストプラクティス 質問する

出力ファイルで使用するためにオブジェクトをカスタム文字列形式にシリアル化するためのベストプラクティス 質問する

特定のビジネス クラスで ToString() のオーバーライドを実装して、Excel 対応のフォーマットを生成し、後で取得して処理する出力ファイルに書き込むところでした。データは次のようになります。

5555555 "LASTN SR, FIRSTN"  5555555555  13956 STREET RD     TOWNSVILLE  MI  48890   25.88   01-003-06-0934

単にフォーマット文字列を作成して をオーバーライドするだけでは大した問題ではありませんToString()が、そうすると、この方法でシリアル化することにしたすべてのオブジェクトの の動作が変わりToString()、 の実装がToString()ライブラリ全体で不揃いになります。

さて、私はIFormatProvider、そしてそれを実装するクラスは良いアイデアのように思えますが、このすべてのロジックをどこに配置すればよいのか、フォーマッタ クラスをどのように構築すればよいのか、まだ少し混乱しています。

オブジェクトから CSV、タブ区切り、またはその他の非 XML の任意の文字列を作成する必要がある場合、皆さんはどうしますか?

ベストアンサー1

リフレクションを使用してオブジェクトのリストから CSV を作成する一般的な方法を次に示します。

public static string ToCsv<T>(string separator, IEnumerable<T> objectlist)
{
    Type t = typeof(T);
    FieldInfo[] fields = t.GetFields();

    string header = String.Join(separator, fields.Select(f => f.Name).ToArray());

    StringBuilder csvdata = new StringBuilder();
    csvdata.AppendLine(header);

    foreach (var o in objectlist) 
        csvdata.AppendLine(ToCsvFields(separator, fields, o));

    return csvdata.ToString();
}

public static string ToCsvFields(string separator, FieldInfo[] fields, object o)
{
    StringBuilder linie = new StringBuilder();

    foreach (var f in fields)
    {
        if (linie.Length > 0)
            linie.Append(separator);

        var x = f.GetValue(o);

        if (x != null)
            linie.Append(x.ToString());
    }

    return linie.ToString();
}

ToCsv() でファイルに直接書き出したり、StringBuilder を IEnumerable と yield ステートメントに置き換えたりするなど、さまざまなバリエーションを作成できます。

おすすめ記事