Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
401 views
in Technique[技术] by (71.8m points)

c# - Best practices for serializing objects to a custom string format for use in an output file

I was just about to implement an override of ToString() on a particular business class in order to produce an Excel-friendly format to write to an output file, which will be picked up later and processed. Here's what the data is supposed to look like:

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

It's no big deal for me to just make a format string and override ToString(), but that will change the behavior of ToString() for any objects I decide to serialize this way, making the implementation of ToString() all ragged across the library.

Now, I've been reading up on IFormatProvider, and a class implementing it sounds like a good idea, but I'm still a little confused about where all this logic should reside and how to build the formatter class.

What do you guys do when you need to make a CSV, tab-delimited or some other non-XML arbitrary string out of an object?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is a generic fashion for creating CSV from a list of objects, using reflection:

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();
}

Many variations can be made, such as writing out directly to a file in ToCsv(), or replacing the StringBuilder with an IEnumerable and yield statements.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...