Writing a C# serializer, running into an issue

I wrote a class that takes an object and outputs a .cs file with code that generates that object. Aka an object to class converter.

https://pastebin.com/WDLygCRs

I’m making this because I’m writing my own custom Windows-forms within monogame, and I want to replicate the experience you get coding with Windows forms/Qt.

My issue is that Monogame’s Color does not expose its ‘innards’, and that I cannot serialize it.

    Color test = new Color();
    List<string> dependencies = new List<string>();
    Debug.WriteLine("Serialation of test color;\n" + CSCreator.CreateFields(test, ref dependencies));

This should output something like
byte R = 55, byte G = 87; byte B = 9; byte A = 98;

But instead it outputs nothing. This is because color.GetType().GetFields() outputs nothing.

Of course I could write an exception for Color, but I’d much rather find a generic way to handle all Monogame objects like this. I’m not sure when this is going to happen with what objects.

Edit: on looking at the source code for color, I saw it uses the
[System.Runtime.Serialization.DataContractAttribute]

It seems like I have to write a method that will invoke Deconstruct, which will be difficult, as every object has a different set of parameters, but it should be manageable.

GetFields only return fields, Color uses Properties. Either use GetProperties or GetMembers instead.

Also, allow me to shamelessly self-promote one of my libs, you might find it handy:

:slight_smile:

2 Likes

9 day bump, I didn’t want to reply until I knew I got it right, but yeah, I needed to check for properties along with fields. I didn’t end up using your library, mostly because I’m mostly done anyway.

I added a pre-emptive ‘hack’ here. There wasn’t any real reason to, but instead of checking for SerializableAttribute I chose to just check if the property has a ‘set’ method. My logic is that while I’m not sure if the user will correctly flag the property as serializable, I can assume if there’s no set method, it’s not meant to be serializable. Not totally sure if that’s a good idea or not, but it makes sense to me.

        foreach (PropertyInfo property in obj.GetType().GetProperties())
        {
            if (property.GetSetMethod() == null) { continue; } // Skip if there is no set; method
            object value = property.GetValue(obj);

            // This is a standard that probably won't be followed.
            // implementing a check for [DataMember] would result
            // in more accurate behavior.
            //if (!value.GetType().GetCustomAttributes(typeof(SerializableAttribute), true).Any()) { continue; } // Skip if property isn't marked as serializable

            if (value == null) { definition = "null"; }
            else { definition = CreateDefinition(value, ref dependencies); }

            field_string.AppendLine($"{property.Name} = {definition}{separating_char}");
        }

Because I want to make "Googler"s happy, my pastebin source code is updated.

Btw, I did end up writing a method to invoke “Deconstruct” and return an object[] with all the out parameters, only to realize that was a total waste of time. :slight_smile: