C# object-oriented programming does not differ much from the C++ model. Below there are major C# class components along with samples.
Defining a Class
A C# [1] class definition starts with the keyword class followed by the class name and the class body enclosed by a pair of curly braces. Following is the general form of a class definition:
<access specifier> class class_name { //Member variables <access specifier> <data type> variable1; <access specifier> <data type> variable2; ... <access specifier> <data type> variableN; //Member methods <access specifier> <return type> method1(parameter_list) { //Method body } <access specifier> <return type> method2(parameter_list) { //Method body } ... <access specifier> <return type> methodN(parameter_list) { //Method body } }
Note:
Example:
using System; namespace BoxApplication { class Box { public double length; //Length of a box public double breadth; //Breadth of a box public double height; //Height of a box } class Boxtester { static void Main(string[] args) { Box Box1 = new Box(); //Declare Box1 of type Box Box Box2 = new Box(); //Declare Box2 of type Box double volume = 0.0; //Store the volume of a box here //Box1 specification Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0; //Box2 specification Box2.height = 10.0; Box2.length = 12.0; Box2.breadth = 13.0; //Volume of Box1 volume = Box1.height * Box1.length * Box1.breadth; Console.WriteLine("Volume of Box1 : {0}", volume); //Volume of Box2 volume = Box2.height * Box2.length * Box2.breadth; Console.WriteLine("Volume of Box2 : {0}", volume); Console.ReadKey(); } } }
Output:
Volume of Box1 : 210 Volume of Box2 : 1560
Member Functions and Encapsulation
A member function of a class is a function that has its definition or its prototype within the class definition similar to any other variable. It operates on an object of the class of which it is a member and has access to all the members of a class for that object.
Member variables are the attributes of an object (from the design perspective), and they are kept private to implement encapsulation. These variables can only be accessed using the public member functions.
Sample:
using System; namespace BoxApplication { class Box { private double length; //Length of a box private double breadth; //Breadth of a box private double height; //Height of a box public void setLength( double len ) { length = len; } public void setBreadth( double bre ) { breadth = bre; } public void setHeight( double hei ) { height = hei; } public double getVolume() { return length * breadth * height; } } class Boxtester { static void Main(string[] args) { Box Box1 = new Box(); //Declare Box1 of type Box Box Box2 = new Box(); double volume; //Declare Box2 of type Box //Box1 specification Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0); //Box2 specification Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0); //Volume of Box1 volume = Box1.getVolume(); Console.WriteLine("Volume of Box1 : {0}" ,volume); //Volume of Box2 volume = Box2.getVolume(); Console.WriteLine("Volume of Box2 : {0}", volume); Console.ReadKey(); } } }
Output:
Volume of Box1 : 210 Volume of Box2 : 1560
C# Constructors
A class constructor is a special member function of a class that is executed whenever we create new objects of that class.
A constructor has the same name as that of a class and does not have any return type.
Example:
using System; namespace LineApplication { class Line { private double length; //Length of a line public Line() { Console.WriteLine("Object is being created"); } public void setLength( double len ) { length = len; } public double getLength() { return length; } static void Main(string[] args) { Line line = new Line(); //Set line length line.setLength(6.0); Console.WriteLine("Length of line : {0}", line.getLength()); Console.ReadKey(); } } }
Output:
Object is being created Length of line : 6
A default constructor has no parameter, but you can make one if you need to pass some setup values on the initialisation - such constructors are called parameterised constructors. This technique helps you to assign an initial value to an object at the time of its creation.
Example:
using System; namespace LineApplication { class Line { private double length; //Length of a line public Line(double len) { //Parameterized constructor Console.WriteLine("Object is being created, length = {0}", len); length = len; } public void setLength( double len ) { length = len; } public double getLength() { return length; } static void Main(string[] args) { Line line = new Line(10.0); Console.WriteLine("Length of line : {0}", line.getLength()); //Set line length line.setLength(6.0); Console.WriteLine("Length of line : {0}", line.getLength()); Console.ReadKey(); } } }
Output:
Object is being created, length = 10 Length of line : 10 Length of line : 6
C# Destructors
A destructor is a special member function of a class executed whenever an object of its class goes out of scope. A destructor has the same name as the class with a prefixed tilde (~), and it can neither return a value nor take any parameters.
C# (.NET environment) has a built-in memory management system that tracks unused objects and releases memory automatically. Still, in constrained memory systems like RPI, it is sometimes essential to manually notify this mechanism about the possibility of releasing memory once the object is no longer used. Here, destructor helps much. Moreover, the destructor can handle hardware-related issues, e.g. close connection, sending a farewell message to the external device, etc.
Destructors cannot be inherited or overloaded.
Example:
using System; namespace LineApplication { class Line { private double length; //Length of a line public Line() { //Constructor Console.WriteLine("Object is being created"); } ~Line() { //destructor Console.WriteLine("Object is being deleted"); } public void setLength( double len ) { length = len; } public double getLength() { return length; } static void Main(string[] args) { Line line = new Line(); //Set line length line.setLength(6.0); Console.WriteLine("Length of line : {0}", line.getLength()); } } }
Output:
Object is being created Length of line : 6 Object is being deleted
Static Members of a C# Class
We can define class members as static using the static keyword. When we declare a class member as static, no matter how many class objects are created, there is only one copy of the static member.
The keyword static implies that only one instance of the member exists for a class. Static variables are used for defining constants because their values can be retrieved by invoking the class without creating an instance. Static variables can be initialised outside the member function or class definition. You can also initialise static variables inside the class definition.
Example:
using System; namespace StaticVarApplication { class StaticVar { public static int num; public void count() { num++; } public int getNum() { return num; } } class StaticTester { static void Main(string[] args) { StaticVar s1 = new StaticVar(); StaticVar s2 = new StaticVar(); s1.count(); s1.count(); s1.count(); s2.count(); s2.count(); s2.count(); Console.WriteLine("Variable num for s1: {0}", s1.getNum()); Console.WriteLine("Variable num for s2: {0}", s2.getNum()); Console.ReadKey(); } } }
Output:
Variable num for s1: 6 Variable num for s2: 6
You can also declare a member function as static. Such functions can access only static variables. The static functions exist even before the object is created. Example:
using System; namespace StaticVarApplication { class StaticVar { public static int num; public void count() { num++; } public static int getNum() { return num; } } class StaticTester { static void Main(string[] args) { StaticVar s = new StaticVar(); s.count(); s.count(); s.count(); Console.WriteLine("Variable num: {0}", StaticVar.getNum()); Console.ReadKey(); } } }
Output:
Variable num: 3
Events occur when a user makes actions like a key press, clicks, mouse movements, etc., or some other occurrence such as system-generated notifications. Applications must respond to events if they occur, e.g. handle interrupts. Events are used during inter-process communication.
Using Delegates With Events
The events are declared and raised in a class. They are associated with the event handlers using delegates within the same or some other class. To publish the event, the class containing it must be defined. It is called the publisher class. Another class that accepts this event is called the subscriber class. Events use the publisher-subscriber model.
The object containing a definition of the event and the delegate is named publisher. The event-delegate association is also defined in this object. A publisher class object invokes the event and is notified to other objects.
A subscriber is an object that accepts the event and provides an event handler. The delegate in the publisher class invokes the method (event handler) of the subscriber class.
Declaring Events
First, a delegate type for the event must be declared to declare an event inside a class. For example,
public delegate string MyDel(string str);
Next, the event itself is declared using the event
keyword:
event MyDel MyEvent;
The preceding code defines a delegate named MyDel
and an event named MyDel
, which invokes the delegate when it is raised.
Example:
using System; namespace SampleApp { public delegate string MyDel(string str); class EventProgram { event MyDel MyEvent; public EventProgram() { this.MyEvent += new MyDel(this.WelcomeUser); } public string WelcomeUser(string username) { return "Welcome " + username; } static void Main(string[] args) { EventProgram obj1 = new EventProgram(); string result = obj1.MyEvent("Tutorials Point"); Console.WriteLine(result); } } }
Output:
Welcome Tutorials Point