Results 1 to 6 of 6

Thread: ReadOnly Properties sort of thing and XML serialization

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Dec 2012
    Posts
    136

    ReadOnly Properties sort of thing and XML serialization

    Hi folks,

    I've done lots of plucking at programming over the last few decades but never achieved anything resembling competence in the field. Now I'm retired and I have the time to slow down, relax, and actually try to accomplish something.

    My current project is to write a game very (very) similar to the old dos game Masters of Orion (which I'll have questions about in the game programming forum later). I've spent the last two weeks messing around with classes and reading up on the basics - fields, properties, constructors, methods etc. Almost unanimously what I've read has always pushed the idea of restricting write access to the fields and properties, concentrating on letting constructors and methods change the values whenever possible.

    So anyway I've got all these classes that I've written and re-written until they seemed nice and efficient, no wasted space, lots of readonly properties etc to prevent unintentionaly changing data, and I've even taken to adding documentation to everything (the nice auto-summary thingy in VS is really handy!).

    So I got far enough that I really wanted to putting game data in on-disk XML files. It only took me a day to figure out how (freakin' easy!) but it completely blew away all my efforts to protect the classes from accidental data changes.

    First, nothing I want to save is allowed to be read-only (kinda makes sense. Saving doesn't require a setter but if you're going to save it that implies you're going to have to load it later, which does.) So all my read-onlys had to be changed to public properties.

    Second, the New() method isn't allowed to have any parameters and I made extensive use of New(). Not a huge deal, I just added a method (named the same in all classes) to do the same things but call it right after instantiating the class.

    So, now on to my search for knowledge. Is there a way to have both XML serialization and also something similar to readonly properties? Even something as simple as hiding public properties from intellisense so they don't show up in the tooltips would be a help.

    Or am I just stuck having public properties for all fields that need to save to disk?

    Thanks for any insights!

  2. #2
    Superbly Moderated NeedSomeAnswers's Avatar
    Join Date
    Jun 2002
    Location
    Manchester uk
    Posts
    2,660

    Re: ReadOnly Properties sort of thing and XML serialization

    but it completely blew away all my efforts to protect the classes from accidental data changes.
    Is there a way to have both XML serialization and also something similar to readonly properties? Even something as simple as hiding public properties from intellisense so they don't show up in the tooltips would be a help.
    So my question would be why do you want to do this?

    Unless you make the class itself public, people cant see your properties externally, and secondly and probably more importantly your in control of your class state so if the data shouldn't be updated dont update it !!

    The reason to make a property readOnly is if your creating a public class with public methods (so that other people can create an instance of your class) they will not be able to save back to that property, only read from it.

    This is important if you dont want a third party to be able to update the value of a property. If that is what your doing then you probably want to use a different class for serialisation if that is your problem.

    Unless there is something you have forgotten to tell us?
    Please Mark your Thread "Resolved", if the query is solved & Rate those who have helped you



  3. #3
    PowerPoster PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Pontypool, Wales
    Posts
    2,474

    Re: ReadOnly Properties sort of thing and XML serialization

    If you really need your classes to have read only properties, and I completely understand your reasoning here, and support serialisation you could consider a second set of classes.

    One approach is to have a second set of classes for Data Transfer Operations (DTOs), your real classes could accept one of these in a Sub New and have a property to return one ready for serialising. Initially it can seem like a lot of work to create these extra classes but in the long run it also allows you to separate your actual classes from the on disk formats as well as achieving your aim of read only properties.

    You might find the DataContract attribute and the DataContractSerializer could help, you lose some control over the output but it will allow you to deserialze to properties with a private setter.

  4. #4

    Thread Starter
    Addicted Member
    Join Date
    Dec 2012
    Posts
    136

    Re: ReadOnly Properties sort of thing and XML serialization

    Wow, sometimes you really get too focused on one thing and can't think at the edges of the box, never mind outside it.

    The second set of classes idea is actually sounds pretty simple. I iterate through my list of classes, sending each instance a class to fill with data and adding it to a second, serializable list which is then written to disk. Reverse that to reconstruct the original list then drop the "loader" list.

    As for why use readonly its pretty much just the gist of what I'm getting by reading on the net. If you make things that shouldn't be changed outside the class read only then nobody can accidentally change it from outside the class. If my program ends up being a multi-person project that'd probably be important but in reality it really helps me not do silly things accidentally.

    I'll try and read up on datacontracts. Had a brief peek and at first blush the two class idea seems a heck of a lot simpler.

    Thanks folks!

  5. #5
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: ReadOnly Properties sort of thing and XML serialization

    I don't want to say "making read-only classes is foolish". There are architectural reasons to favor them. When your classes are immutable there are entire sets of problems you give up, particularly around multithreading.

    But.

    Every architecture decision has costs and benefits. When you make your types immutable, you tend to need to write code that is more functional in nature. VB isn't oriented towards that very well, and few people actually study writing functional code. (I admit this is one of my weakest areas despite knowing I should shore it up for years.)

    That's the part people are leaving out when you're reading on the net. When you design your application this way, you gain some things but other things get more complex. I'm not familiar enough with it to provide a good primer, but you've already seen one problem: serialization gets more complex.

    I do not like the MS serialization infrastructure, but it does have a secret backdoor intended for these situations. It's hard to find this unless you stumble on the documentation, because there's no good way for the language to enforce it. It's called "Custom Serialization". It's a little janky because it dates all the way back to .NET 1.0, and a lot of neat features didn't exist yet.

    Step 1 is the "writing" part. ISerializable defines a GetObjectData() method:
    Code:
    Sub GetObjectData (
    	info As SerializationInfo,
    	context As StreamingContext
    )
    This method is called as part of serialization, before the serialization stream is generated. The SerializationInfo parameter is basically a Dictionary/Hashtable where you can store arbitrary data. When the object is deserialized, it has a chance to get that data again. How?

    Step 2 is the "reading" part, and can't really be part of the interface. When an object is being deserialized, if it implements a very special constructor, that constructor will be called:
    Code:
    Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
    If you put something in the SerializationInfo when the object was serialized, that something will be there when it's deserialized!

    So this is an example of an immutable class that can still be serialized/deserialized, no need for an intermediate class:
    Code:
    Public Class Person
        Implements ISerializable
    
        Private _name As String
        Public ReadOnly Property Name As String
            Get
                Return _name
            End Get
        End 
    
        Private _age As Integer
        Public ReadOnly Property Age As Integer
            Get
                Return _age
            End Get
        End 
    
        Public Sub New(ByVal name As String, ByVal age As String)
            _name = name
            _age = age
        End Sub
    
        Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            _name = info.GetString("name")
            _age = info.GetInt32("age")
        End Sub
    
        Public Overridable Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext)
            info.AddValue("name", Name)
            info.AddValue("age", Age)
        End Sub
    End Class
    This is pretty specific to the MS serialization framework, but you can generally adapt something similar for others. For example, when I use JSON serialization, my types usually have this method:
    Code:
    Public Shared Function FromJson(ByVal json As String) As Whatever
    Since the code is part of the type itself, it can still manipulate the private fields of the object it creates. This lets me use the parser to set the unsettable!
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Dec 2012
    Posts
    136

    Re: ReadOnly Properties sort of thing and XML serialization

    That's very cool, lets you keep stuff private and also serialize easily. Thanks for the info. Doing some reading up at MS.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width