41
class Person
{
    public string m_name;
    private int m_age; // << how do I serialize the darn little rat?
}

Simple question yet it seems like a big mess when trying to answer it.
Everyone suggest to use public getter/setter but my app is too big and making a getter/setter for each member would just cause maintainability issues.

Am I forced to create a custom serialization here or is there a magic attribute for such members?
How do I serialize private class members?

Edit #1:
Ok everyone, sorry for the unclarity, I was a bit upset when I wrote this question, it was several hours after trying to find the solution.
Anyway, here are more facts:
1. I'm trying to XML serialize this class. Currently I'm using System.Xml.Serialization.XmlSerializer.
2. I'm serializing into XML to have version compatibility, which as far as I understand binary doesn't offer me that.
3.I was hoping that there's a certain attribute like:

class Person
{
    public string m_name;
    [SerializeThat(ElementName="Age")]
    private int m_age; // << how do I serialize the darn little rat?
}

OR (continue of fact #3) an attribute that goes on the class which would look like:

[Serializable(DoPrivate = true, DoProtected = true)]
class Person
{
    public string m_name;
    private int m_age; // << how do I serialize the darn little rat?
}

Now, what can I do to achieve it?

Poni
  • 11,061
  • 25
  • 80
  • 121
  • 2
    I guess public int m_age; should be private? Or else, there is no problem, is it? – Jan Sverre Nov 30 '10 at 14:50
  • 3
    What kind of serialization are you trying to do? – Travis Gockel Nov 30 '10 at 14:53
  • What "big mess" are you getting? I don't see why you can't just stick [Serializable] on the class and be done with it. Maybe there's something you are over-simplifying in your example code that means you're hiding the cause of the problem. – Jon Hanna Nov 30 '10 at 15:06
  • 7
    "how do I serialize the darn little rat?" HAHAHAAHHAHA! +1 for making me laugh out loud. – Lzh Oct 13 '12 at 00:56
  • 1
    Possible duplicate of [Serializing private member data](http://stackoverflow.com/questions/802711/serializing-private-member-data) – Chris Pickford Apr 06 '17 at 13:08

7 Answers7

20

Going on the assumption of a typo, I'd like to redirect you to this SO article where the solution is to use a DataContractSerializer instead.

Community
  • 1
  • 1
Brad Christie
  • 100,477
  • 16
  • 156
  • 200
  • Hi Brad and thanks for the answer - I can't even compile the code, maybe because I'm trying to do so on an ASP.NET web app?? – Poni Nov 30 '10 at 23:19
  • The usual: "error CS0246: The type or namespace name 'DataMember' could not be found". Weird. – Poni Nov 30 '10 at 23:37
  • Not to insult intelligence, but are you including System.Runtime.Serialization in your references? **EDIT** If so, right click the reference and go to properties and select "copy local" and see if that resolves it. – Brad Christie Nov 30 '10 at 23:38
  • @Brad - thanks, I've been confusing the 'Runtime' part of this reference with "Xml", and that's why I didn't get the DataContract. – Poni Dec 01 '10 at 00:31
  • Everything working now, or still fooling with the attributes? You can probably break it down to a console application and test the bare minimum (directing the output to Console.Out) – Brad Christie Dec 01 '10 at 00:38
  • Ok, finally I can say that DataContractSerializer is what I was looking for. It makes things just a *bit* more messy yet on the other hand it gives me some better control. The only problem with it actually is that there are no (advanced) examples of it, and in my case I needed that for many classes which derive from many other classes. Thanks again! – Poni Dec 01 '10 at 03:39
  • For derived classes you're probably going to need to decorate the base class with `[KnownType(typeof(InheritedClass))]` (consistent with how WCF services work). But it ultimately should provide the end goal you're looking for. – Brad Christie Dec 01 '10 at 14:03
13

Don't know if you can use DataContract. But with this you could write:

[DataContract]
class Person
{
    [DataMember]
    public string m_name;

    [DataMember]
    private int m_age;
}

The advantage of DataContract that you can serialize private fields and your class doesn't need a default constructor.

Oliver
  • 43,366
  • 8
  • 94
  • 151
  • Thanks as well. I'm checking this as we're speaking. – Poni Dec 01 '10 at 02:08
  • Good answer Oliver, thanks. Wish you'd phrase it a bit differently, that'd save me time (: – Poni Dec 01 '10 at 03:42
  • 1
    If no custom handling (like exclusion) is required, this could be even simpler, just have `Serializable` attribute and DataContractSerializer will now choose all members of the class without having to mark them with `[DataMember]` – nawfal Jul 10 '14 at 10:46
8

If you use BinaryFormatter, it will go for your class' private parts.

Mark every class of yours with [Serializable] or you won't go far...

Also, look this: Why is Serializable Attribute required for an object to be serialized

Since you need XML, maybe you can pull yourself though it all with SoapFormatter. See this.

Apropos version compatibility: I use BinaryFormatter and have no problems with schema upgrades. Try it please: you can handle schema changes yourself, our simply replace null pointers left out by the Deserialize with appropriate default constructs. If you don't really need the features that XML provide, go binary - you'll never look back.

Also, one more EDIT:

BF will readily resolve all your multiple references so it won't create multiple instances of the same reference over and over. Guess you won't get that with XmlSerializer - it's obvious that it has no place for storing that information.

Example:

class Data
{
    int a;
}

class ManyData
{
    Data d1;
    Data d2;
}

...

ManyData md=new ManyData();
md.d1=new Data();
md.d2=md.d1;

Try serializing/deserializing md with several alternatives...

Community
  • 1
  • 1
Daniel Mošmondor
  • 19,718
  • 12
  • 58
  • 99
  • Nononno, it's fine. Me use BF all the time, and we live in happy marriage :) – Daniel Mošmondor Nov 30 '10 at 15:13
  • 2
    @Daniel - not all marriages end well. I'm very much **not** a fan of BF – Marc Gravell Nov 30 '10 at 15:37
  • @Daniel - for binary? I'm biased, but I'd use protobuf-net; faster, smaller output, version-safe and interoperable between other platforms. – Marc Gravell Nov 30 '10 at 16:07
  • 9
    "it will go for your class' private parts." - Ouch, that sounds painful. :) – Ani Nov 30 '10 at 17:25
  • Thanks Daniel although I'm looking for an XML serialization as stated in edit #1. – Poni Nov 30 '10 at 23:21
  • @Poni - here, I edited the answer myself, both to try to give you better BF nudge and some XML alternatives... – Daniel Mošmondor Nov 30 '10 at 23:40
  • 2
    @Daniel - I'd try the binary but at the moment the specs require the serialization to be in XML, probably because it goes to a database which should be also read by human. Putting that aside, I can't hold myself from telling you that I wish every member of SO, and actually at every community, would have the good attitude you have - keep it up, you're on your way to the 100K rep. (: – Poni Dec 01 '10 at 03:36
5

What serializer ate you currently using? Almost all should work with that. But public fields *is*a bad idea. XmlSerializer and JavaScriptSerializer will ignore private members. DataContractSerializer and protobuf-net can deal with private members. BinaryFormatter handles fields (public or private), but is not a good idea IMO for numerous reasons.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Marc thanks for taking the time to reply - as I've written in edit #1 I'm trying to XML serialize this class. Additionally, 'DataContractSerializer' doesn't seem to exist on an ASP.NET Web Application. Using VS2008. What can you say? – Poni Nov 30 '10 at 23:23
  • @Poni - add a reference to System.Runtime.Serialization.dll – Marc Gravell Nov 30 '10 at 23:29
  • 'XmlSerializer' exists without that ref... One little missing attribute does so much pain :/ – Poni Nov 30 '10 at 23:40
  • Yo Marc - thanks again. Actually Brad's answer which relates to you on that other SO question helped me realize some stuff. Therefore, really, thanks! – Poni Dec 01 '10 at 03:41
2

ISerializable? http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx

Master Morality
  • 5,837
  • 6
  • 31
  • 43
0

You better write custom serializer

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx

Sid C
  • 67
  • 2
0

Use IXmlSerializable interface and control fields that you want to serialize:

public interface IXmlSerializable
{
    XmlSchema GetSchema();
    void ReadXml(XmlReader reader);
    void WriteXml(XmlWriter writer);
}
Stas BZ
  • 1,184
  • 1
  • 17
  • 36