[Serializable]
class Person : ISerializable
{
public string
FirstName { get; set; }
public string LastName
{ get; set; }
public Person(string
FirstName, string LastName) {
this.FirstName = FirstName;
this.LastName = LastName;
}
protected Person(SerializationInfo info, StreamingContext ctx) {
FirstName = info.GetString(nameof(FirstName));
LastName = info.GetString(nameof(LastName));
}
public string FullName
{ get { return $"{FirstName} {LastName}"; } }
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext ctx) {
info.AddValue(nameof(FirstName), FirstName);
info.AddValue(nameof(LastName), LastName);
}
}
[Serializable]
class Employee : Person
{
static int
_runningId;
public int Id { get; private set; } =
_runningId++;
public Employee(string
FirstName, string LastName) : base(FirstName, LastName) { }
protected Employee(SerializationInfo info, StreamingContext ctx) : base(info,
ctx) {
Id = info.GetInt32(nameof(Id));
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void
GetObjectData(SerializationInfo info, StreamingContext ctx) {
info.AddValue(nameof(Id), Id);
base.GetObjectData(info, ctx);
}
}
- The interface enforces the implementation of the GetObjectData method, this method fires on serialization, which gives you the opportunity to encrypt your data. For simplicity sake we're using the SercurityPermission attribute, but you could implement whatever mechanism you please.
- Then we add a constructor that is leveraged by the BinaryFormater to rebuild our objects.
- Because we use inheritance we only implement ISerializable on our base class
- We override the GetObjectData method in our superclasses and call the base implementation of it
- We call the base deserializable constructor from our superclasses.
Now our use of the BinaryFormater doesn't really change all that much... or at all
class Program
{
static void Main(string[] args)
{
var ppl = new Person[] {
new Person("John", "Smith"), new Person("Jane","Doe"),
new Employee("Sally","Johnson"),new Person("Alejandro", "Cruz"),
new Person("Diago","Pendaz"), new Employee("Tim","Chan")};
var formatter = new BinaryFormatter();
using (var fs = new FileStream(@"c:\people.data", FileMode.Create, FileAccess.Write))
formatter.Serialize(fs, ppl);
Person[] People;
using (var fs = new FileStream(@"c:\people.data", FileMode.Open, FileAccess.Read))
People = formatter.Deserialize(fs) as Person[];
foreach (var p in People)
Console.WriteLine(p.FullName);
}
}
Implementing the ISerailizable interface is no trivial matter here's a list of caveats to look out for.