Let's suppose I have to serialize an object of a class Car in levels e.g. Internal and Public. Some of the properties in the Public level should not be serialized as they are internal.
At this moment the 'easiest' way I can think of to achieve this is by using inheritance:
class CarPublic {
public int PropX {get;set}
}
class CarInternal: CarPublic {
public string PropY {get;set}
}
Then I could
object ToSerialize() {
CarInternal car = GetCar();
if( level == Level.Public ) {
return car as CarPublic;
} else {
return car;
}
}
The result of the ToSerialize() is taken by a framework (I don't have control over) and serialized to JSON or XML.
I omitted the XML serialization attributes for simplicity.
This feels like a hack and hacks take you only so far. Is there better way (ways?) to achieve this?
I think its clear by now, but I would like to avoid writing my own serialization methods for JSON and XML.
Thanks in advance Tymek
==EDIT
To clarify, I want to be able to serialize multiple levels:
class Car0 {
public int PropA {get;set}
}
class Car1: Car0 {
public string PropB {get;set}
}
class Car2: Car1 {
public int PropC {get;set}
}
class Car3: Car2 {
public string PropD {get;set}
}
and
object ToSerialize( Level level ) {
Car3 car = GetCar();
switch( level ) {
case Level.Zero: return car as Car0;
case Level.One: return car as Car1;
case Level.Two: return car as Car3;
case Level.Three: return car as Car4;
}
return null;
}
== Chosen approach
I marked Marc Gravell's answer as the answer, as it provides the generic information of how C# and it's 'standard' components support what I asked for.
However I think the best approach for my problem is to use proxy classes as shown above and have the class being serialized in this multi-level pattern with methods like shown below.
public interface ICar {
Car0 As0();
Car1 As1();
Car2 As2();
Car3 As3();
...
}
This allows keeping the Car0..3 classes very simple, with only properties, to maintain and understand.
This depends a lot on what serialization framework you are using. You mention xml and json - well, the first thing to note is that you can just decorate with:
[XmlIgnore]
public int PropX {get;set;}
or
[ScriptIgnore]
public int PropX {get;set;}
which XmlSerializer
and JavascriptSerializer
will respond to. If you need to make the decision on a per-instance basis, there is the ShouldSerialize*
and *Specified
patterns:
public bool ShouldSerializePropX() {
// return true to serialize, false to omit
}
The above is a name-based pattern, that is used by XmlSerializer
and others; it has a twin:
[XmlIgnore, Browsable(false)]
public bool PropXSpecified {
get { /* return true to serialize, false to omit */ }
set { /* can just drop this value - don't need to assign */ }
}
You don't need to do anything to wire them up - they work automatically.
Different serializers allow different patterns.
In addition, sometimes you can add things like [XmlIgnore]
at runtime - for example via XmlAttributeOverrides
, or the equivalent for any given serializer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With