/* In this example of the visitor pattern, there are (initially) three kinds of visitees: grad student, undergrad student, and since the students are to exist in a collection, a default "no student", which plays the role of the algebraic identity (rational form of null). The modifier "internal" means that the item is visible (public) to all parts of the program that are compiled together. */ namespace visitorpatternexp { ////////////////////// using System; public interface student // abstract visitee { object accept(svisitor v); } public interface svisitor // abstract visitor { object visitu(undergrad u); object visitg(grad g); object visitn(nostudent n); } // super class for what all students (visitees) have in common: public class basicstudent { internal string name; // name of student internal double gpa; // gpa of student internal double tuition; // cost of tuition for student internal student next; // pointer to next student (forms linked list) public basicstudent(string n, double g) // constructor { name = n; gpa = g; } } // basicstudent // Concrete visitee classes public class undergrad : basicstudent, student { internal string major; // undergrads have a major public undergrad(string n, double g, string m) : base(n,g) { major = m; tuition = 600; // per credit } public object accept(svisitor v) { return v.visitu(this); } }//undergrad public class grad : basicstudent, student { internal string thesis; // grads have a thesis topic public grad(string n, double g, string t) : base(n,g) { thesis=t; tuition = 700; } public object accept(svisitor v) { return v.visitg(this); } }//grad public class nostudent : student { public object accept(svisitor v) { return v.visitn(this); } } }//////////////////////