1

This is a very straightforward question, I have been unable to find a solution on here relevant to my problem.

Given the following single object

    Foo foo = new Foo
{
    A = "Tom",
    B = "Mark",
    C = "Paul",
    D = "John"
};

I need the following output:

Tom,Mark,Paul,John

When Serializing the object using:

string s = JsonConvert.SerializeObject(foo);

I get the following:

{ A = "Tom", B = "Mark", C = "Paul", D = "John" }

Note : This is not a list its a single instance of the class.

I know I can achieve this by overriding a string in my class but I want to know if there is simpler way to do this?

WhiteSpider
  • 385
  • 1
  • 3
  • 10
  • Why dont you just overwrite ToString and concat the fields. Then serialize the string – Romano Zumbé Jul 16 '19 at 08:24
  • what do you mean overwrite ToString please elaborate? – WhiteSpider Jul 16 '19 at 08:26
  • 1
    see here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/how-to-override-the-tostring-method – Sohaib Jundi Jul 16 '19 at 08:27
  • JSON seems to be the wrong format to serialize to ("Tom,Mark..." is not valid JSON) , a CSV format might be more appropriate – MindSwipe Jul 16 '19 at 08:31
  • 1
    Did you mean override? I have already done that, as I stated in my question, Im looking for another way. – WhiteSpider Jul 16 '19 at 08:32
  • Serializing is nowhere near easier than just using low level features of the language – Romano Zumbé Jul 16 '19 at 08:33
  • @RomanoZumbé can you explain how the `ToString()` method is a low level feature of the language? – MindSwipe Jul 16 '19 at 08:36
  • @MindSwipe Overriding is a lowlevel feature of C# and ToString is implemented in `object`. Therefore it is allways available to be overridden by every class. Nothing gets involved, that isn't allready involved. Serialization needs a multitude of other classes to be used – Romano Zumbé Jul 16 '19 at 08:38
  • @RomanoZumbé that's not low level. When I think of low level I think of pointer manipulation and memory allocation. ToString is a fundamental method that every class either implicitly or explicitly inherits from System.Object. Also it has nothing to do with the language, the language doesn't provide you with the ToString method, the framework does – MindSwipe Jul 16 '19 at 08:41
  • @MindSwipe as I just said "Overriding is a lowlevel feature of C#". Whatever you want to understand by lowlevel is not important. But it is a basic feature, that is not inherited by any other language feature but a basic part of the language. As I further said "and ToString is implemented in object. Therefore it is allways available to be overridden by every class". So you're just repeating what I've said – Romano Zumbé Jul 16 '19 at 08:47
  • 1
    @RomanoZumbé I see where the confusion happened, I misread "Overriding is a low level feature of C#" as "Overriding a low level feature of C#"... My bad – MindSwipe Jul 16 '19 at 08:59

2 Answers2

1

You could override ToString for the class and just convert foo to a string :

public class Foo
{
    public string A = string.Empty;
    public string B = string.Empty;
    public string C = string.Empty;
    public string D = string.Empty;

    public override string ToString()
    {
        return A + "," + B + "," + C + "," + D;
    }
}

Foo foo = new Foo
{
    A = "Tom",
    B = "Mark",
    C = "Paul",
    D = "John"
};

string s = foo.ToString();
Romano Zumbé
  • 7,893
  • 4
  • 33
  • 55
  • 1
    I recommend using [string interpolation](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated) instead of concatenation using `+`es – MindSwipe Jul 16 '19 at 08:34
  • You're right! Every + generates a new string object in memory. I just wanted to keep my answer as simple as possible to keep it understandable as it is really low level – Romano Zumbé Jul 16 '19 at 08:35
  • I've already got this solution, I did state that in the question, thats why i was asking for another way, but thanks for the solution. – WhiteSpider Jul 16 '19 at 08:38
  • Sorry, I understood "overriding a string" as just having another property, that yields A + B + C + D – Romano Zumbé Jul 16 '19 at 08:40
  • So just to be clear overriding is the best way to do this? – WhiteSpider Jul 16 '19 at 08:41
  • @WhiteSpider no, it requires unnecessary effort when extending classes and also uses up the ToString method. ToString should only be used in a debugging/ developing environment – MindSwipe Jul 16 '19 at 08:42
  • @MindSwipe ok so how would you do it? – WhiteSpider Jul 16 '19 at 08:47
  • @MindSwipe How do you come to that conclusion? It is absolutely normal to override ToString in real world usecases. It is extremely efficient in terms of ressource usage. If you need to use ToString in another context just have a property that concatenates the values – Romano Zumbé Jul 16 '19 at 08:49
  • @WhiteSpider I'm currently typing up an answer that uses Reflection to do this – MindSwipe Jul 16 '19 at 08:55
  • @MindSwipe That is nearly the worst solution possible. It uses so much more ressources in comparison. If you scale this up the performance will be drastically worse. Only thing worse I could imagine would be to write it to a file and read it back – Romano Zumbé Jul 16 '19 at 08:58
  • 2
    @RomanoZumbé I am very much not a troll, simply dyslexic and somewhat stubborn. Sometime ago someone told me to never override ToString and that's what I haven't been doing since then. But after further investigation ([this](https://stackoverflow.com/a/10278430/9363973) SO answer helped a lot) I see I was wrong. Overriding ToString is a perfectly valid way of going about it – MindSwipe Jul 16 '19 at 09:03
  • @MindSwipe Sorry for the troll comment. Deleted it right away. – Romano Zumbé Jul 16 '19 at 09:05
0

If you don't mind going around the houses, you could serialise the object to JSON, then deserialise it into a dictionary then pull the values of the dictionary to get a simple list of strings.

string s = JsonConvert.SerializeObject(obj);
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
List<string> propertyValues = dictionary.Values.toList();
string myOvercomplicatedString = String.Join(',', propertyValues);

I don't have any C# tools in front of me so this might not run perfectly, but you should be able to get it working pretty easily. This isn't a great solution - I would absolutely prefer to define a method that just pulls them together directly or an override of ToString - but if you're determined to avoid that then a solution along these lines will work.

glenatron
  • 11,018
  • 13
  • 64
  • 112
  • 2
    this will work but as you say its probably better to override ToString. Thanks – WhiteSpider Jul 16 '19 at 08:57
  • Sure, I figured you had a pretty good solution in Romano's response, but it was interesting to figure out how to answer the specific question you asked. – glenatron Jul 16 '19 at 09:21