// Example demonstrating class hierarchies and inheritance // Extension of Lecture 3, using implicit and explicit serialisation // This version uses pre-defined attributes (see Liberty, "Programming C# 3.0", Chapter 20) // See also: https://msdn.microsoft.com/en-us/library/4abbf6k0%28v=vs.110%29.aspx // ----------------------------------------------------------------------------- using System; using System.Text; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Xml.Serialization; /* using System.Runtime.CompilerServices; using System.Diagnostics; */ // The base class: generic information on a person [Serializable] class Person{ // private data fields for Person; uses a mixture of access modifiers for demonstration private string _fName; private string _lName; private string _address; // public properties to access the data public string fName { get { return _fName; } set { _fName = value; } } public string lName { get { return _lName; } set { _lName = value; } } public string address { get { return _address; } set { _address = value; } } public Person(string fName, string lName, string address){ this.fName = fName; this.lName = lName; this.address = address; } public override string ToString() { return String.Format("Name: {0} {1}\tAddress: {2}", this.fName, this.lName, this.address); } public virtual string Serialise() { return "Person.Serialise: To be implemented"; } } // Student is a sub-class of Person, and inherits its data-fields and methods [Serializable] class Student: Person{ // the private data for Student private string _matricNo; private string _degree; // the properties to access the data public string degree { get { return _degree; } set { _degree = value; } } public string matricNo { get { return _matricNo; } set { _matricNo = value; } } // constructor public Student(string fName, string lName, string address, string matricNo, string degree): base(fName, lName, address) { this.matricNo = matricNo; this.degree = degree; } /* ------------------------------------------------------- */ /* This does explicit serialisation; we don't need that with the serialisable attribute */ // override ToString as an example of serialisation public override string ToString() { string base_str = base.ToString(); string this_str = String.Format("MatricNo: {0}\tDegree: {1}", this.matricNo, this.degree); return base_str+"\n"+this_str; } // A different way to implement ToString; it is less generic, // because it relies on knowledge of the field in all parent classes public string ToString0() { return String.Format("Name: {0} {1}\tAddress: {2}\nMatricNo: {3}\tDegree: {4}", this.fName, this.lName, this.address, this.matricNo, this.degree); } } // Lecturer is another sub-class of Person, and inherits its data-fields and methods [Serializable] class Lecturer: Person{ // the pivate data private string _officeNo; // the property to access the data public string officeNo { get { return _officeNo; } set { _officeNo = value; } } public Lecturer(string fName, string lName, string address, string officeNo): base(fName, lName, address) { this.officeNo = officeNo; } /* ------------------------------------------------------- */ /* This does explicit serialisation; we don't need that with the serialisable attribute */ // override ToString as an example of serialisation public override string ToString() { string base_str = base.ToString(); string this_str = String.Format("OfficeNo: {0}", this.officeNo); return base_str+"\n"+this_str; } } class Test{ public static void Main(){ // Person p = new Person("John", "Smith", "Edinburgh"); Student s = new Student("Brian", "Hillman", "London", "99124678", "CS"); Lecturer l = new Lecturer("Hans-Wolfgang", "Loidl", "Edinburgh", "G48"); Console.WriteLine("\nHere we use the overriden ToString() method, implemented as a generic serialisation method:"); Console.WriteLine("Student: {0} ", s.ToString0()); Console.WriteLine("Student: {0} ", s.ToString()); Console.WriteLine("Lecturer: {0} ", l.ToString()); /* ------------------------------------------------------- */ IFormatter formatter = new BinaryFormatter(); Stream streamOut = new FileStream("ThisPerson.bin", FileMode.Create, FileAccess.Write, FileShare.None); formatter.Serialize(streamOut, l); streamOut.Close(); /* ------------------------------------------------------- */ // IFormatter formatter = new BinaryFormatter(); Stream streamIn = new FileStream("ThisPerson.bin", FileMode.Open, FileAccess.Read, FileShare.Read); Lecturer l1 = (Lecturer) formatter.Deserialize(streamIn); streamIn.Close(); // Test the result: contents should be the same as in l Console.WriteLine("Lecturer after serialise/deserialise:\n{0}", l1.ToString()); } }