Reputation: 1494
I have an abstract base class (BaseMessage
) with a method SerializeProperties
that serializes all it's properties into a byte array and holds them in a protected variable of type byte[]
.
There is a class inherited from this abstract base class (BaseCommandMessage
) which is also abstract and introduces a few more properties. I want this class to implement SerializeProperties
forcing it to serialize all it's local properties and add it to the byte array.
After that I have a concrete class that inherits from that abstract class (CommandMessage
) that needs to implement SerializeProperties
and serialize it's properties to the byte array.
This can go on for X number of generations but I want to enforce that each class must implement SerializeProperties
and I'd like to do all this without using reflection.
Furthermore if I have a statement such as:
BaseMessage message = new CommandMessage();
message.SerializeProperties();
It should serialize the BaseMessage properties, the BaseCommandMessage properties and finally the CommandMessage properties sequentially.
i.e. call the SerializeProperties
method of the BaseMessage
class, the SerializeProperties
method of the BaseCommandMessage
class and finally the SerializeProperties
of the CommandMessage
class respectively.
I hope that makes sense!
Thanks
p.s.
I can do this with one generation i.e. in my base class I have an implemented method called SerializeMyProperties which serializes all it's properties and then calls an abstract or virtual method SerializeProperties which the inheriting class can implement. That way it serializes it's own properties and then serializes the inherited class but I can't go past +2 generations.
Upvotes: 3
Views: 212
Reputation: 127553
I can do this with one generation i.e. in my base class I have an implemented method called SerializeMyProperties which serializes all it's properties and then calls an abstract or virtual method SerializeProperties which the inheriting class can implement. That way it serializes it's own properties and then serializes the inherited class but I can't go past +2 generations.
You likely had it, you probably just made a mistake in how you did SerializeMyProperties. Here is the pattern I use. The public class that is exposed to the user is non vitual (this step is not nessesary but it makes it convenient if the base class needs to perform some extra steps on the agragated work, like my call to ToArray()
), it calls a private virtual function where each child calls it's parent's version before it starts to do it's work.
abstract class Foo
{
public byte[] SerializeProperties()
{
var props = new List<byte>();
SerializeMyProperties(props);
return props.ToArray();
}
private virtual void SerializeMyProperties(List<byte> props)
{
byte[] serializedByteArrayForThisInstance;
//Magic!
props.AddRange(serializedByteArrayForThisInstance);
}
}
class Bar : Foo
{
private virtual void SerializeMyProperties(List<byte> props)
{
//Call the Foo's SerializeMyProperties first so it fills the first part of the list
base.SerializeMyProperties(props);
byte[] serializedByteArrayForThisInstanceToo;
//Even More Magic!
props.AddRange(serializedByteArrayForThisInstanceToo);
}
}
class Baz : Bar
{
private virtual void SerializeMyProperties(List<byte> props)
{
//Call the Bar's SerializeMyProperties first so it fills the first two parts of the list
base.SerializeMyProperties(props);
byte[] iAmRunningOutOfVariableNames;
//Here Be Dragons!
props.AddRange(iAmRunningOutOfVariableNames);
}
}
Upvotes: 0
Reputation: 9837
Make sure that each class that provides an overload for SerializeProperties
first makes a call to base.SerializeProperties
. It might be better to change the method to return the bytes, and then augment the array with each generation. This should allow each generation to do what it needs to, and enable future generations to do what they need to.
class BaseMessage
{
protected virtual byte[] SerializeProperties()
{
var bytes = new List<byte>();
bytes.AddRange(...); // serialize BaseMessage properties
return bytes.ToArray();
}
}
class BaseCommandMessage
{
protected override byte[] SerializeProperties()
{
var bytes = new List<byte>(base.SerializeProperties());
bytes.AddRange(...); // serialize BaseCommandMessage properties
return bytes.ToArray();
}
}
class CommandMessage
{
protected override byte[] SerializeProperties()
{
// A call to this method will call BaseCommandMessage.SerializeProperties,
// and indirectly call BaseMessage.SerializeProperties
var bytes = new List<byte>(base.SerializeProperties());
bytes.AddRange(...); // serialize CommandMessage properties
return bytes.ToArray();
}
}
Upvotes: 4